""" A date string, such as 2007-12-03, compliant with the `full-date` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. """ scalar Date """ A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. """ scalar DateTime scalar Json input CourseStudentsFilterInput { readyForSubmission: Boolean isActiveDegreeStudent: Boolean courseIds: [ID!] degreeIds: [ID!] statuses: [CourseStudentStatus!] createdGTE: String createdLTE: String """ ISO 8601. Inclusive lower bound on `accomplished`. Always pair with `statuses: [PASSED]`: only there is `accomplished` the pass time. """ accomplishedGTE: String """ ISO 8601. Inclusive upper bound on `accomplished`; a bare date covers that whole day (UTC). """ accomplishedLTE: String """ Woolf user ids — the `studentId` a STUDENT_PASSED_COURSE webhook carries. Limits to those students. """ userIds: [ID!] """ Your college's own student ids (the external id you set on each student). Limits to those students. """ externalIds: [String!] } input AssetInput { contentType: String fileName: String importUrl: String } input AttendanceInput { studentId: String! resourceId: String! timestamp: String } """ A cross-listing tag in your own college. A COLLEGE tag needs no id: it is always your college. """ input CrossListingTagInput { level: CrossListingTagLevel! """Required for a COURSE tag.""" courseId: ID """Required for a DEGREE tag.""" degreeId: ID } """ The levels a college can tag at. UNIVERSITY is reserved for Woolf staff. """ enum CrossListingTagLevel { COLLEGE DEGREE COURSE } input EvaluationInput { courseId: String! studentIds: [String!]! tierId: ID } input FeedbackInput { activityId: ID resourceId: String studentId: String! teacherId: String content: String assets: [AssetInput!] evidenceAssets: [AssetInput!] } input GradeInput { activityId: ID resourceId: String studentId: String! teacherId: String weightId: ID value: Float! assets: [AssetInput!] evidenceAssets: [AssetInput!] } input ResourceCreateInput { name: String! kind: ResourceKind isGradeRequired: Boolean = true cohortName: String externalId: String content: String workload: Int weightIds: [ID!] assets: [AssetInput!] tags: [String!] cohortNames: [String!] teacherIds: [ID!] } input ResourceModifyInput { name: String kind: ResourceKind isGradeRequired: Boolean cohortName: String externalId: String content: String workload: Int weightIds: [ID!] assets: [AssetInput!] tags: [String!] cohortNames: [String!] teacherIds: [ID!] } input StudentInput { externalId: String nameFirst: String nameLast: String } input SubmissionInput { activityId: ID resourceId: String studentId: String content: String assets: [AssetInput!] evidenceAssets: [AssetInput!] } input TeacherInput { externalId: String } type ActivityPaginationResult { count: Int! list: [Activity]! } type Activity { id: ID! created: DateTime! updated: DateTime! userId: ID! collegeId: ID! degreeId: ID weightId: ID courseId: ID resourceId: ID data: Json! kind: ActivityKind! status: ActivityStatus! resourceKind: ResourceKind grade: Float assets: [Asset!]! evidenceAssets: [Asset!]! } enum ActivityKind { addFeedback addGrade submitAssignment consumeResource attendMeeting } type ActivityOutput { activityId: String! assets: [AssetUpload!]! evidenceAssets: [AssetUpload!]! """ Non-fatal problems with the recorded activity, e.g. attendance on a meeting that is not VERIFIED and so does not count yet. Only mutations whose description mentions `warnings` populate it; on the others it is always empty and says nothing about whether the activity counts. """ warnings: [ActivityWarning!]! } enum ActivityStatus { ACTIVE ARCHIVED PENDING REJECTED } type ActivityWarning { """ Stable machine-readable code: RESOURCE_NOT_VERIFIED or RESOURCE_HAS_NO_WORKLOAD. New codes may be added; treat unknown codes as informational. """ code: String! """ Human-readable explanation for logs and support. Informational only: the wording may change, so branch on `code`, not on this text. """ message: String! } type Asset { id: ID! fileName: String! contentType: String downloadUrl: String updated: DateTime! created: DateTime! } type AssetUpload { headers: Json uploadUrl: String } type College { id: ID! name: String! descr: Json deanId: ID deanName: String deanEmail: String status: CollegeStatus! rejectionReason: String updated: DateTime! created: DateTime! degrees: [Degree!]! teachers: [CollegeStaff!]! } enum CollegeStatus { DRAFT VERIFIED REJECTED ARCHIVED TEACH_OUT } type CollegeStaff { id: ID! externalId: String created: DateTime! updated: DateTime! name: String! email: String! } type CourseStudent { id: ID! userId: ID! updated: DateTime! created: DateTime! """ The pass time on PASSED rows. Only meaningful there: an ACTIVE or SUBMITTED row can still hold the time its last submission was rejected. """ accomplished: DateTime courseId: ID! rejectionReason: String runningAverage: Float! finalAverage: Float! degreeId: ID status: CourseStudentStatus workloadRequired: Int! workloadCompleted: Int! meetingRequired: Int! meetingCompleted: Int! publicationReviewedCompleted: Int! publicationReviewedRequired: Int! assignmentRequired: Int! assignmentCompleted: Int! assignmentSummativeRequired: Int! assignmentSummativeCompleted: Int! } enum CourseStudentStatus { ACTIVE SUBMITTED PASSED FAILED } type CourseStudentPaginationResult { count: Int! list: [CourseStudent]! } type Course { id: ID! updated: DateTime! created: DateTime! status: CourseStatus! rejectionReason: String name: String! descr: String! weights: [Weight!]! workloadRequired: Int! workload: Int! publicationRequired: Int! publicationReviewedRequired: Int! meetingRequired: Int! assignmentRequired: Int! assignmentSummativeRequired: Int! } enum CourseStatus { DRAFT REJECTED VERIFIED ARCHIVED } type CoursePaginationResult { count: Int! list: [Course]! } enum Currency { USD EUR INR AED GBP PHP UAH THB TND NGN MAD DZD XOF KES } enum DegreeStudentPaymentStatus { UNPAID PAID } enum DegreeStudentStatus { PENDING ACTIVE REJECTED SUBMITTED COMPLETED ARCHIVED PAUSED } type DegreeStudent { id: ID! degreeId: ID! updated: DateTime! created: DateTime! status: DegreeStudentStatus identityStatus: ComplianceStepStatus! qualificationStatus: ComplianceStepStatus! motivationStatus: ComplianceStepStatus! agreementStatus: ComplianceStepStatus! approvalStatus: ComplianceStepStatus! workloadConsumed: Int! workloadRequired: Int! workloadCompleted: Int! onboardingStarted: DateTime identityTimestamp: DateTime qualificationTimestamp: DateTime motivationTimestamp: DateTime agreementTimestamp: DateTime approvalTimestamp: DateTime paymentTimestamp: DateTime paymentStatus: DegreeStudentPaymentStatus! activated: DateTime rejectionReason: String } enum ComplianceStepStatus { PENDING REJECTED SUBMITTED COMPLETED } type Degree { id: ID! updated: DateTime! created: DateTime! rejectionReason: String name: String! descr: Json courses: [Course!]! } enum JobKind { BULK_ACTIVITY_IMPORT } enum JobStatus { PENDING PROCESSING COMPLETED FAILED } type JobDetails { id: String! status: JobStatus! kind: JobKind fileName: String fileKind: String url: JobFileInfo resultsUrl: JobFileInfo assets: [Asset!]! created: DateTime! updated: DateTime! successCount: Int errorCount: Int } type JobFileInfo { path: String downloadUrl: String headers: Json } input Pagination { skip: Int! = 0 """ Limits the number of returned records. To return all records specify `null` """ take: Int = 100 } type ResourcePaginationResult { count: Int! list: [Resource]! } type CrossListingTag { id: ID! level: String! collegeId: ID collegeName: String degreeId: ID degreeName: String courseId: ID courseName: String order: Int } type Resource { id: ID! externalId: String created: DateTime! updated: DateTime! courseId: ID cohortId: ID isV2: Boolean! crossListingTags: [CrossListingTag!]! cohortName: String cohortNames: [String!] rejectionReason: String name: String! content: String workload: Int! workloadMultiplier: Float! workloadExecution: Int! kind: ResourceKind! status: ResourceStatus! weights: [Weight!] assets: [Asset!]! } enum ResourceKind { ASSIGNMENT ASSIGNMENT_SUMMATIVE MEETING GENERAL PUBLICATION PUBLICATION_REVIEWED } type ResourceOutput { resource: Resource! assets: [AssetUpload!]! } enum ResourceStatus { DRAFT REJECTED SUBMITTED VERIFIED ARCHIVED } enum DegreeCourseKind { COMPULSORY ELECTIVE } enum GradingScheme { NUMERIC PASS_FAIL } type StudentDegreeProgressSnapshot { degree: StudentDegreeProgressSnapshotDegree! degreeId: ID! degreeStudentId: ID! finalAverage: Float gpa: Float status: DegreeStudentStatus! workloadCompletedHours: Float! workloadCompletedMinutes: Int! workloadConsumedHours: Float! workloadConsumedMinutes: Int! workloadInProgressHours: Float! workloadInProgressMinutes: Int! workloadProvisionalHours: Float! workloadProvisionalMinutes: Int! workloadRequiredHours: Float! workloadRequiredMinutes: Int! } type StudentDegreeProgressSnapshotCourse { courseId: String! degreeCourseKind: DegreeCourseKind! finalAverage: Float name: String! provisionalWorkloadHours: Float! provisionalWorkloadMinutes: Int! provisionalWorkloadSolidHours: Float! provisionalWorkloadSolidMinutes: Int! requirementCounters: StudentDegreeProgressSnapshotCourseRequirementCounters! runningAverage: Float status: CourseStudentStatus workloadConsumedHours: Float! workloadConsumedMinutes: Int! workloadRequiredHours: Float! workloadRequiredMinutes: Int! } type StudentDegreeProgressSnapshotCourseRequirementCounters { accomplished: DateTime consumedResourceAssignmentAmount: Int! consumedResourceAssignmentSummativeAmount: Int! consumedResourceMeetingAmount: Int! consumedResourcePublicationReviewedAmount: Int! gradingScheme: GradingScheme hasDegreeAffiliation: Boolean! isOnboardingCompleted: Boolean! minimumCourseWorkloadHours: Float! minimumCourseWorkloadMinutes: Int! resourceAssignmentAmountRequired: Int! resourceAssignmentSummativeAmountRequired: Int! resourceMeetingAmountRequired: Int! resourcePublicationReviewedAmountRequired: Int! } type StudentDegreeProgressSnapshotDegree { id: ID! name: String! specializations: [StudentDegreeProgressSnapshotTier!]! tiers: [StudentDegreeProgressSnapshotTier!]! workloadRequiredHours: Float workloadRequiredMinutes: Int } type StudentDegreeProgressSnapshotTier { courses: [StudentDegreeProgressSnapshotCourse!]! cumulativeWorkloadConsumedHours: Float! cumulativeWorkloadConsumedMinutes: Int! cumulativeWorkloadProvisionalHours: Float! cumulativeWorkloadProvisionalMinutes: Int! cumulativeWorkloadProvisionalSolidHours: Float! cumulativeWorkloadProvisionalSolidMinutes: Int! id: ID! kind: TierKind! name: String! position: Int! tierProgress: StudentDegreeProgressSnapshotTierProgress tierWorkloadRequiredHours: Float! tierWorkloadRequiredMinutes: Int! } type StudentDegreeProgressSnapshotTierProgress { exemptionGrantedAt: DateTime exemptionSource: TierExemptionSource isExempted: Boolean! workloadCompletedMinutes: Int! workloadCompletedHours: Float! workloadCompulsoryCompletedMinutes: Int! workloadCompulsoryCompletedHours: Float! workloadCompulsoryRequiredMinutes: Int! workloadCompulsoryRequiredHours: Float! workloadElectiveCompletedMinutes: Int! workloadElectiveCompletedHours: Float! workloadElectiveRequiredMinutes: Int! workloadElectiveRequiredHours: Float! workloadRequiredMinutes: Int! workloadRequiredHours: Float! workloadTransferredMinutes: Int! workloadTransferredHours: Float! } enum TierExemptionSource { AIRLOCK_API AIRLOCK_SDK AMS IMPORT IMPORT_RPL RPL_REQUEST STAI_CREDIT UNKNOWN } enum TierKind { TIER SPECIALIZATION } type Student { id: ID! externalId: String name: String! email: String! updated: DateTime! created: DateTime! degrees: [DegreeStudent!]! courses: [CourseStudent!]! } type StudentPaginationResult { count: Int! list: [Student]! } type Webhook { id: ID! url: String! events: [WebhookEvent!]! created: String! updated: String! } type WebhookPaginationResult { count: Int! list: [Webhook]! } type Weight { id: ID! created: DateTime! updated: DateTime! courseId: ID! name: String! percentage: Int! quantity: Int! } enum WebhookEvent { REJECTED_RESOURCE STUDENT_PASSED_COURSE IMPORTED_ASSETS DEGREE_STUDENT_ACTIVATED DEGREE_STUDENT_COMPLETED_APPLICATION DEGREE_STUDENT_ARCHIVED DEGREE_STUDENT_DELISTED DEGREE_STUDENT_COMPLETED ACTIVITY_UPLOAD_FINISHED } type Query { activities(courseId: String, kinds: [ActivityKind!], pagination: Pagination = {skip: 0, take: 100}, resourceId: String, resourceKinds: [ResourceKind!], statuses: [ActivityStatus!], studentId: String): ActivityPaginationResult! activity(id: ID!): Activity! college: College! courseStudents(filters: CourseStudentsFilterInput, pagination: Pagination = {skip: 0, take: 200}): CourseStudentPaginationResult! course(id: ID!): Course! courses(degreeId: ID, pagination: Pagination = {skip: 0, take: 200}, statuses: [CourseStatus!]): CoursePaginationResult! jobDetails(jobId: String!): JobDetails! myDegreeProgress(degreeId: ID!): StudentDegreeProgressSnapshot! resource(id: String!): Resource! resources(courseId: ID, kinds: [ResourceKind!], pagination: Pagination = {skip: 0, take: 200}, statuses: [ResourceStatus!]): ResourcePaginationResult! studentDegreeProgress(degreeId: ID!, id: String!): StudentDegreeProgressSnapshot! student(id: String!): Student! students(courseId: ID, degreeId: ID, pagination: Pagination = {skip: 0, take: 200}): StudentPaginationResult! webhooks(pagination: Pagination = {skip: 0, take: 200}): WebhookPaginationResult! } type Mutation { """ Records a student's attendance at a meeting. The attendance is always stored; `warnings` lists the reasons it will not count toward the student's course requirements yet (RESOURCE_NOT_VERIFIED, RESOURCE_HAS_NO_WORKLOAD). """ addAttendance(attendance: AttendanceInput!): ActivityOutput! addFeedback(feedback: FeedbackInput!): ActivityOutput! addGrade(grade: GradeInput!): ActivityOutput! """ Cross-lists one of your college's resources to more of your courses, degrees or your whole college, so its workload also counts there. Tags the resource already has are skipped, so the call is safe to repeat. Past completions of the resource that no course could credit yet are retried against the new tags; a completion already allocated to a course stays where it is. """ addResourceCrossListingTags(resourceId: ID!, tags: [CrossListingTagInput!]!): Resource! addResource(courseId: ID!, resource: ResourceCreateInput!): ResourceOutput! addStudentToCollege(email: String!, student: StudentInput): Student! addStudentToDegree(currency: Currency, degreeId: ID!, email: String!, isScholarship: Boolean, student: StudentInput, tuitionCost: Int): Student! addSubmission(submission: SubmissionInput!): ActivityOutput! addTeacherToCollege(courseIds: [ID!], email: String!, teacher: TeacherInput): CollegeStaff! addWebhook(events: [WebhookEvent!]!, url: String!): Webhook archiveActivity(activityId: ID!): Boolean archiveCourseProgress(courseId: ID!, studentId: ID!): Boolean archiveDegreeStudent(degreeId: ID, degreeStudentId: ID, reason: String!, studentId: ID): Boolean! bulkUploadActivity: Json! changeDegreeStudentScholarship(degreeId: ID, degreeStudentId: ID, isScholarship: Boolean!, studentId: ID): Boolean! changeEmail(email: String!, id: ID!): Boolean! changeWebhook(events: [WebhookEvent!], id: ID!, url: String): Webhook generateUserToken(id: String!): String! modifyResource(id: ID!, resource: ResourceModifyInput!): ResourceOutput! pauseDegreeStudent(degreeId: ID, degreeStudentId: ID, pauseFrom: Date, pauseTo: Date, reason: String!, studentId: ID): Boolean! """ Removes cross-listing tags of your college from one of its resources. Tags the resource does not have are ignored. The tag linking a resource to its own course cannot be removed. Removing a tag stops new completions counting toward that course; a completion already provisionally allocated to it is not reallocated. """ removeResourceCrossListingTags(resourceId: ID!, tags: [CrossListingTagInput!]!): Resource! removeWebhook(id: ID!): Boolean submitStudentsForEvaluation(evaluation: EvaluationInput!): [ID] unpauseDegreeStudent(degreeId: ID, degreeStudentId: ID, studentId: ID): Boolean! }