-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathschema.graphql
1170 lines (1101 loc) · 25.3 KB
/
schema.graphql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
type AnnotatedDoc {
"""
Official short identifier for this document
"""
id: UUID!
"""
Full title of the document
"""
title: String!
"""
Date and time this document was written or created
"""
date: Date
"""
When the document was bookmarked by the current user, if it was.
"""
bookmarkedOn: Date
"""
The original source(s) of this document, the most important first.
"""
sources: [SourceAttribution!]!
"""
Where the source document came from, maybe the name of a collection
"""
collection: DocumentCollection
"""
The genre of the document, used to group similar ones
"""
genre: String
"""
Images of each source document page, in order
"""
pageImages: IiifImages
"""
The people involved in producing this document, including the original
author, translators, and annotators
"""
contributors: [Contributor!]!
"""
Is this document a reference source (unstructured list of words)?
Otherwise, it is considered a structured document with a translation.
"""
isReference: Boolean!
"""
The audio recording resource for this entire document
"""
audioRecording: AudioSlice
"""
Arbitrary number used for manually ordering documents in a collection.
For collections without manual ordering, use zero here.
"""
orderIndex: Int!
"""
URL-ready slug for this document, generated from the title
"""
slug: String!
"""
Segments of the document paired with their respective rough translations
"""
translatedPages: [DocumentPage!]
"""
All the words contained in this document, dropping structural formatting
like line and page breaks.
"""
forms(start: Int, end: Int): [AnnotatedForm!]!
formCount: Int!
"""
All words in the document that have unanalyzed or unfamiliar parts.
These words need to be corrected or reviewed further.
"""
unresolvedForms: [AnnotatedForm!]!
"""
Collection chapters that contain this document.
"""
chapters: [CollectionChapter!]
}
"""
A single word in an annotated document.
One word contains several layers of interpretation, including the original
source text, multiple layers of linguistic annotation, and annotator notes.
TODO Split into two types, one for migration and one for SQL + GraphQL
"""
type AnnotatedForm {
"""
Original source text
"""
source: String!
"""
A normalized version of the word
"""
normalizedSource: String
"""
Underlying phonemic representation of this word
"""
phonemic: String
"""
English gloss for the whole word
"""
englishGloss: [String!]!
"""
Further details about the annotation layers, including uncertainty
"""
commentary: String
"""
The character index of a mid-word line break, if there is one
"""
lineBreak: Int
"""
The character index of a mid-word page break, if there is one
"""
pageBreak: Int
"""
Position of the form within the context of its parent document
"""
position: PositionInDocument!
"""
The date and time this form was recorded
"""
dateRecorded: Date
"""
The audio for this word that was ingested from GoogleSheets, if there is any.
"""
ingestedAudioTrack: AudioSlice
"""
The root morpheme of the word.
For example, a verb form glossed as "he catches" might have a root morpheme
corresponding to "catch."
"""
root: WordSegment
romanizedSource(system: CherokeeOrthography!): String
segments(system: CherokeeOrthography!): [WordSegment!]!
"""
All other observed words with the same root morpheme as this word.
"""
similarForms: [AnnotatedForm!]!
"""
The document that contains this word.
"""
document: AnnotatedDoc
"""
Number of words preceding this one in the containing document
"""
index: Int!
"""
Unique identifier of the containing document
"""
documentId: UUID!
"""
Unique identifier of this form
"""
id: UUID!
"""
A slices of audio associated with this word in the context of a document.
This audio has been selected by an editor from contributions, or is the
same as the ingested audio track, if one is available.
"""
editedAudio: [AudioSlice!]!
"""
Audio for this word that has been recorded by community members. Will be
empty if user does not have access to uncurated contributions.
TODO! User guard for contributors only
"""
userContributedAudio: [AudioSlice!]!
"""
Get comments on this word
"""
comments: [Comment!]!
}
"""
A single word in an annotated document that can be edited.
All fields except id are optional.
"""
input AnnotatedFormUpdate {
"""
Unique identifier of the form
"""
id: UUID!
"""
Possible update to source content
"""
source: String
"""
Possible update to commentary
"""
commentary: String
"""
Updated segments
"""
segments: [MorphemeSegmentUpdate!]
}
"""
Element within a spreadsheet before being transformed into a full document.
"""
union AnnotatedSeg = AnnotatedForm | LineBreak
"""
Request to attach user-recorded audio to a word
"""
input AttachAudioToWordInput {
"""
Word to bind audio to
"""
wordId: UUID!
"""
A URL to a Cloudfront-proxied user-recorded pronunciation of a word.
A new resource will be created to represent the recording if one does not exist already
"""
contributorAudioUrl: String!
}
"""
A segment of audio representing a document, word, phrase,
or other audio unit
"""
type AudioSlice {
"""
The unique id for this audio slice. Will not be present if audio has not been inserted
"""
sliceId: String
"""
The audio resource this audio slice is taken from, generally pulled from the DRS API
"""
resourceUrl: String!
"""
An audio slice this slice is a subunit of, if there is one
"""
parentTrack: String
"""
When the track was recorded, if available
"""
recordedAt: Date
"""
Which user recorded the tracked, if uploaded by a user
"""
recordedBy: User
"""
True if audio should be shown to Readers.
"""
includeInEditedCollection: Boolean!
"""
Last Editor to decide if audio should be included in edited collection.
"""
editedBy: User
"""
This slice's relative position to other slices within an audio resource
"""
index: Int!
"""
The time (in seconds) in the parent track where this slice begins.
"""
startTime: Int
"""
The time (in seconds) in the parent track where this slice ends.
"""
endTime: Int
}
"""
One representation of Cherokee phonology.
There are several different writing systems for Cherokee phonology and we
want to convert between them.
This type enumerates all of the systems that we support and provides
conversion from our internal orthography into any of these.
"""
enum CherokeeOrthography {
TAOC
CRG
LEARNER
}
"""
Structure to represent a single chapter. Used to send data to the front end.
"""
type CollectionChapter {
"""
UUID for the chapter
"""
id: UUID!
"""
Full title of the chapter
"""
title: String!
"""
ID of WordPress page with text of the chapter
"""
wordpressId: Int
"""
Order within the parent chapter or collection
"""
indexInParent: Int!
"""
Whether the chapter is an "Intro" or "Body" chapter
"""
section: CollectionSection!
"""
Full path of the chapter
"""
path: [String!]!
slug: String!
document: AnnotatedDoc
"""
Breadcrumbs from the top-level archive down to where this document lives.
"""
breadcrumbs: [DocumentCollection!]!
}
"""
Enum to represent the sections in an edited collection
"""
enum CollectionSection {
INTRO
BODY
CREDIT
}
"""
A comment a user has made on some piece of a document.
"""
type Comment {
"""
Unique identifier of this comment
"""
id: UUID!
"""
When the comment was posted
"""
postedAt: DateTime!
"""
Who posted the comment
"""
postedBy: User!
"""
The text of the comment
"""
textContent: String!
"""
An optional classification of the comment's content
"""
commentType: CommentType
"""
Whether the comment has been edited since it was posted
"""
edited: Boolean!
}
"""
Type representing the object that a comment is attached to
"""
union CommentParent = AnnotatedForm | DocumentParagraph
"""
An enum listing the possible types that a comment could be attached to
"""
enum CommentParentType {
WORD
PARAGRAPH
}
"""
A type describing the kind of comment being made
"""
enum CommentType {
STORY
SUGGESTION
QUESTION
}
"""
Used for updating comments.
All fields except id are optional.
"""
input CommentUpdate {
id: UUID!
"""
The text of the comment
"""
textContent: String
commentType: CommentType
edited: Boolean!
}
"""
A block of content, which may be one of several types.
Each page contains several blocks.
This type is intended to enable a custom page builder on the front-end for
content editors.
"""
union ContentBlock = Markdown | Gallery
"""
An individual or organization that contributed to the creation or analysis
of a particular document or source. Each contributor has a name and a role
that specifies the type of their contributions.
"""
type Contributor {
"""
Full name of the contributor
"""
name: String!
"""
The role that defines most of their contributions to the associated item
"""
role: String!
details: ContributorDetails
}
"""
Basic personal details of an individual contributor, which can be retrieved
from a particular instance of [`Contributor`].
They may have transcribed a handwritten manuscript, translated it into
English, or analyzed it for linguistic information.
This information can be used to track who contributed to the development of
each individual document, and track contributions to the archive as a whole.
"""
type ContributorDetails {
"""
Full name of this person, this exact string must be used to identify
them elsewhere, like in the attribution for a particular document.
"""
fullName: String!
"""
Alternate name of this person, may be in a different language or writing
system. Used only for descriptive purposes.
"""
alternateName: String
"""
The optional date that this contributor was born on.
"""
birthDate: Date
}
"""
Request to update if a piece of audio should be included in an edited collection
"""
input CurateWordAudioInput {
"""
Word audio is attached to
"""
wordId: UUID!
"""
Audio to include/exclude
"""
audioSliceId: UUID!
"""
New value
"""
includeInEditedCollection: Boolean!
}
type Date {
"""
The year of this date
"""
year: Int!
"""
The month of this date
"""
month: Int!
"""
The day of this date
"""
day: Int!
"""
Formatted version of the date for humans to read
"""
formattedDate: String!
}
input DateInput {
day: Int!
month: Int!
year: Int!
}
type DateTime {
"""
UNIX timestamp of the datetime, useful for sorting
"""
timestamp: Int!
"""
Just the Date component of this DateTime, useful for user-facing display
"""
date: Date!
}
"""
Input object for deleting an existing comment
"""
input DeleteCommentInput {
"""
ID of the comment to delete
"""
commentId: UUID!
}
"""
Delete a contributor attribution for a document based on the two ids
"""
input DeleteContributorAttribution {
documentId: UUID!
contributorId: UUID!
}
type DocumentCollection {
"""
Full name of this collection
"""
name: String!
"""
URL-ready slug for this collection, generated from the name
"""
slug: String!
"""
All documents that are part of this collection
TODO Try to unify this return type into AnnotatedDoc
This probably requires adding a document_ids field so that we can just
pass that to the dataloader below.
"""
documents: [DocumentReference!]!
}
"""
Used for updating document metadata.
All fields except id are optional.
"""
input DocumentMetadataUpdate {
id: UUID!
title: String
writtenAt: DateInput
}
type DocumentPage {
"""
One-indexed page number
"""
pageNumber: String!
"""
Scan of this page as a IIIF resource, if there is one
"""
image: PageImage
"""
Contents of this page as a list of paragraphs
"""
paragraphs: [DocumentParagraph!]!
}
"""
One paragraph within a [`DocumentPage`]
"""
type DocumentParagraph {
"""
Unique identifier for this paragraph
"""
id: UUID!
"""
English translation of the whole paragraph
"""
translation: String!
"""
1-indexed position of this paragraph in a document
"""
index: Int!
"""
Source text of the paragraph broken down into words
"""
source: [AnnotatedSeg!]!
"""
Get comments on this paragraph
"""
comments: [Comment!]!
}
"""
Reference to a document with a limited subset of fields, namely no contents
of the document.
"""
type DocumentReference {
"""
Database ID for the document
"""
id: UUID!
"""
Unique short name
"""
shortName: String!
"""
Long title of the document
"""
title: String!
"""
Date the document was produced (or `None` if unknown)
"""
date: Date
"""
Index of the document within its group, used purely for ordering
"""
orderIndex: Int!
"""
URL slug for this document
"""
slug: String!
}
"""
The kind of a document in terms of what body it lives within. A reference
document is a dictionary or grammar for example, while a corpus document
might be a letter, journal, or notice.
"""
enum DocumentType {
REFERENCE
CORPUS
}
"""
Structure to represent an edited collection. Missing certain fields and chapters in it.
Used for sending data to the front end
"""
type EditedCollection {
"""
UUID for the collection
"""
id: UUID!
"""
Full title of the collection
"""
title: String!
"""
ID of WordPress menu for navigating the collection
"""
wordpressMenuId: Int
"""
URL slug for the collection, like "cwkw"
"""
slug: String!
chapters: [CollectionChapter!]
}
type FormsInTime {
start: Date
end: Date
forms: [AnnotatedForm!]!
}
"""
A gallery of images, which may be rendered as a slideshow or lightbox.
"""
type Gallery {
mediaUrls: [String!]!
}
"""
A rectangle slice of something, usually a large document image.
Units are a percentage of the containing document.
This is more useful than pixels because we can more easily compare
geometries between images of different resolutions. For example, we could identify
all items in any bottom-right corner with Geometry(90%, 90%, 100%, 100%).
Physical units would be better, but IIIF only allows pixels and percentages.
Potential use case:
Each document is represented by an ordered list of [AnnotatedForm]s. Each
form has some geometry on the source image. There are a bunch of other
annotations on the source image that are unordered. These may be specific
syllabary characters, notes about the handwriting, etc. Using MongoDB
comparison queries, we can request a list of all spatial annotations
on the same document that lie within or around the geometry of this specific word.
"""
type Geometry {
xMin: Float!
yMin: Float!
xMax: Float!
yMax: Float!
}
type IiifImages {
"""
Information about the data source for this set of images
"""
source: ImageSource!
"""
List of urls for all the images in this collection
"""
urls: [String!]!
}
type ImageSource {
"""
Base URL for the IIIF server
"""
url: String!
}
"""
A scalar that can represent any JSON value.
"""
scalar JSON
"""
Start of a new line
"""
type LineBreak {
"""
Index of this line break within the document. i.e. Indicates the start
of line X.
"""
index: Int!
}
"""
A block of prose content, formatted with [Markdown](https://commonmark.org/).
"""
type Markdown {
content: String!
}
"""
One particular morpheme and all the known words that contain that exact morpheme.
"""
type MorphemeReference {
"""
Phonemic shape of the morpheme.
"""
morpheme: String!
"""
List of words that contain this morpheme.
"""
forms: [AnnotatedForm!]!
}
"""
A single unit of meaning and its gloss which can be edited.
"""
input MorphemeSegmentUpdate {
"""
Which Cherokee representation system is this segment written with?
"""
system: CherokeeOrthography
"""
Source language representation of this segment.
"""
morpheme: String!
"""
Target language representation of this segment.
"""
gloss: String!
"""
This field determines what character should separate this segment from
the next one when reconstituting the full segmentation string.
"""
role: WordSegmentRole!
}
"""
A concrete representation of a particular functional morpheme.
"""
type MorphemeTag {
"""
Internal representation of this functional item, which may be one or
more word parts in the raw annotation. For example, ["X", "Y"] could map
to "Z" in a particular display format.
"""
internalTags: [String!]!
"""
How this morpheme is represented in a gloss
"""
tag: String!
"""
Plain English title of the morpheme tag
"""
title: String!
"""
How this morpheme looks in original language data
"""
shape: String
"""
URL to an external page with more details about this morpheme.
"""
detailsUrl: String
"""
A prose description of what this morpheme means and how it works in
context.
"""
definition: String!
"""
What kind of morpheme is this? Examples are "Prepronominal Prefix" or
"Aspectual Suffix"
"""
morphemeType: String!
"""
Overrides the segment type of instances of this tag.
"""
roleOverride: WordSegmentRole
}
type Mutation {
"""
Mutation must have at least one visible field for introspection to work
correctly, so we just provide an API version which might be useful in
the future.
"""
apiVersion: String!
"""
Delete a comment.
Will fail if the user making the request is not the poster.
"""
deleteComment(input: DeleteCommentInput!): CommentParent!
"""
Post a new comment on a given object
"""
postComment(input: PostCommentInput!): CommentParent!
"""
Update a comment
"""
updateComment(comment: CommentUpdate!): CommentParent!
"""
Mutation for adding/changing contributor attributions
"""
updateContributorAttribution(contribution: UpdateContributorAttribution!): UUID!
"""
Mutation for deleting contributor attributions
"""
deleteContributorAttribution(contribution: DeleteContributorAttribution!): UUID!
"""
Mutation for paragraph and translation editing
"""
updateParagraph(paragraph: ParagraphUpdate!): DocumentParagraph!
updatePage(data: JSON!): Boolean!
updateAnnotation(data: JSON!): Boolean!
updateWord(word: AnnotatedFormUpdate!): AnnotatedForm!
"""
Adds a bookmark to the user's list of bookmarks.
"""
addBookmark(documentId: UUID!): AnnotatedDoc!
"""
Removes a bookmark from a user's list of bookmarks
"""
removeBookmark(documentId: UUID!): AnnotatedDoc!
"""
Decide if a piece audio should be included in edited collection
"""
curateWordAudio(input: CurateWordAudioInput!): AnnotatedForm!
"""
Attach audio that has already been uploaded to S3 to a particular word
Assumes user requesting mutation recoreded the audio
"""
attachAudioToWord(input: AttachAudioToWordInput!): AnnotatedForm!
updateDocumentMetadata(document: DocumentMetadataUpdate!): UUID!
}
"""
A website page which lives at a specific URL and has a list of blocks that
define its content.
"""
type Page {
"""
The path that this page lives at, which also uniquely identifies it.
For example, "/our-team"
"""
id: String!
title: String!
body: [ContentBlock!]!
}
type PageImage {
"""
The IIIF source this page image comes from
"""
source: ImageSource!
"""
The full IIIF url for this image resource
"""
url: String!
}
"""
A paragraph in an annotated document that can be edited.
"""
input ParagraphUpdate {
"""
Unique identifier of the form
"""
id: UUID!
"""
English translation of the paragraph
"""
translation: String
}
"""
The reference position within a document of one specific form
"""
type PositionInDocument {
"""
What document is this item within?
"""
documentId: UUID!
"""
What page is it on (starting from 1)? May be a single page or range of pages.
"""
pageNumber: String!
"""
How many items come before this one in the whole document?
1-indexed position indicating where the form sits in the ordering of all
forms in the document. Used for relative ordering of forms from the
same document.
"""
index: Int!
"""
What section of the document image corresponds to this item?
"""
geometry: Geometry
"""
Standard page reference for this position, which can be used in citation.
Generally formatted like ID:PAGE, i.e "DF2018:55"
"""
pageReference: String!
"""
Index reference for this position, more specific than `page_reference`.
Generally used in corpus documents where there are few pages containing
many forms each. Example: "WJ23:#21"
"""
indexReference: String!
iiifUrl: String
}
"""
Input object for posting a new comment on some object
"""
input PostCommentInput {
"""
ID of the object that is being commented on
"""
parentId: UUID!
"""
Type of the object being commented on
"""
parentType: CommentParentType!
"""
Content of the comment
"""
textContent: String!
"""
A classifcation for the comment (optional)
"""
commentType: CommentType
}
type Query {
allEditedCollections: [EditedCollection!]!
editedCollection(slug: String!): EditedCollection
"""
Retrieves a chapter and its contents by its collection and chapter slug.
"""
chapter(collectionSlug: String!, chapterSlug: String!): CollectionChapter
"""
List of all the functional morpheme tags available
"""
allTags(system: CherokeeOrthography!): [MorphemeTag!]!
"""
Listing of all documents excluding their contents by default
"""
allDocuments: [AnnotatedDoc!]!
"""
List of all content pages
"""
allPages: [Page!]!
"""
List of all the document collections available.
"""
allCollections: [DocumentCollection!]!
collection(slug: String!): DocumentCollection!
"""
Retrieves a full document from its unique name.
"""
document(slug: String!): AnnotatedDoc
"""
Retrieves all documents that are bookmarked by the current user.
"""
bookmarkedDocuments: [AnnotatedDoc!]!
"""
Retrieves a full document from its unique identifier.
"""
documentByUuid(id: UUID!): AnnotatedDoc
"""
Retrieves a full document from its unique identifier.
"""
page(id: String!): Page
"""
Lists all forms containing a morpheme with the given gloss.
Groups these words by the phonemic shape of the target morpheme.