Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions sources/apollo/courses/course.datasources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint no-useless-constructor: "off", class-methods-use-this: "off" */

const CourseModel = require('./course.model.js')
const { DataSource } = require('apollo-datasource');

class CourseAPI extends DataSource {
constructor() {
super();
}
// eslint-disable-next-line no-empty-function
initialize(_) {}

getCourseById(id) {
return CourseModel.findById(id);
}

getCourseBySubjectCode(subjectCode) {
return CourseModel.findOne({subjectCode});
}

addCourse(course){
const ltp={
lecture: course.ltp[0],
tutorial: course.ltp[1],
// eslint-disable-next-line no-magic-numbers
practical: course.ltp[2]
}
const courseObject = new CourseModel({
subjectCode: course.subjectCode,
name: course.name,
ltp,
credits: course.credits
});
return courseObject.save();
}
}

module.exports = CourseAPI;
65 changes: 65 additions & 0 deletions sources/apollo/courses/course.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const { Schema, model } = require('mongoose');

const courseSchema = new Schema(
{
subjectCode:{
type: String,
required: true,
trim: true,
unique: true,
uppercase: true,
},
name:{
type: String,
required: true,
trim: true,
},
ltp:{
lecture:{
type: Number,
required: true,
min: 0,
},
tutorial:{
type: Number,
required: true,
min: 0,
},
practical:{
type: Number,
required: true,
min: 0,
}
},
credits:{
type: Number,
required: true,
min: 0,
},
schemaVersion: {
type: Number,
required: true,
default: 1,
min: 1,
},
createdBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: false,
default: null, //TODo: Remove after making helper function for this field
},
updatedBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: false,
default: null,
},

},
{
timestamps: true,
},
);
courseSchema.path('subjectCode').index({ unique: true });

module.exports = model('Course', courseSchema);
13 changes: 13 additions & 0 deletions sources/apollo/courses/course.resolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/** @format */
/*eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }]*/
const queries = {
courseById: (_, args, { dataSources }, __) => dataSources.CourseAPI.getCourseById(args.id),

courseBySubjectCode: (_, args, { dataSources }, __) => dataSources.CourseAPI.getCourseBySubjectCode(args.subjectCode)
};

const mutations = {
addCourse: (_, {course}, { dataSources }, __) => dataSources.CourseAPI.addCourse(course),
}

module.exports = { queries, mutations };
37 changes: 37 additions & 0 deletions sources/apollo/courses/course.schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/** @format */

const types = `
type LTP{
lecture: Int
tutorial: Int
practical: Int
}
type Course{
id:ID
subjectCode : String
name : String
ltp : LTP
credits : Int
}
input CourseInputType{
subjectCode : String!
name : String!
ltp : [Int!]
credits : Int!
}
`;

const queries = `
courseBySubjectCode(subjectCode:String!):Course
courseById(id:ID!):Course
`;

const mutations = `
addCourse(course:CourseInputType!):Course
`;

module.exports = { types, queries, mutations };

// updateCourse(id:ID!,course:CourseInputType!):Course
// deleteCourse(id:ID!):Course
// List courses by search | Use Atlas Search
6 changes: 4 additions & 2 deletions sources/apollo/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ const Event = require('./events/event.resolver.js');
const Club = require('./clubs/club.resolver.js');
const AccessLevel = require('./accessLevels/accessLevel.resolver.js');
const Story = require('./stories/story.resolver.js');
const Course = require('./courses/course.resolver.js');
const Timetable = require('./timetables/timetable.resolver.js');
const { GraphQLDateTime } =require ("graphql-iso-date");

const FieldResolver = {};
const Query = {};
const Mutation = {};

const schemas = [User, Event, Club, AccessLevel,Story];
schemas.forEach(s => {
const schemas = [User, Event, Club, AccessLevel,Story, Course, Timetable];
schemas.forEach((s) => {
Object.assign(FieldResolver, s.fieldResolvers);
Object.assign(Query, s.queries);
Object.assign(Mutation, s.mutations);
Expand Down
7 changes: 5 additions & 2 deletions sources/apollo/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ const Venue = require('./venues/venue.schema.js');
const Story = require('./stories/story.schema.js');
const Access = require('./accessLevels/accessLevel.schema.js');
const ErrorClass = require('./errorClass/error.schema.js');
const Course = require('./courses/course.schema.js');
const Timetable = require('./timetables/timetable.schema.js');
const {GraphQLDateTime} = require('graphql-iso-date');

const types = [];
const queries = [];
const mutations = [];

const schemas = [User, Event, Club, Venue, Access, ErrorClass,Story];
schemas.forEach(s => {
const schemas = [User, Event, Club, Venue, Access, ErrorClass,Story, Course, Timetable];
schemas.forEach((s) => {
types.push(s.types);
queries.push(s.queries);
mutations.push(s.mutations);
Expand Down
6 changes: 5 additions & 1 deletion sources/apollo/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const EventAPI = require('./events/event.datasources.js');
const VenueAPI = require('./venues/venue.datasources.js');
const AccessLevelAPI = require('./accessLevels/accessLevel.datasources.js');
const StoryAPI = require('./stories/story.datasources.js');
const CourseAPI = require('./courses/course.datasources.js');
const TimetableAPI = require('./timetables/timetable.datasources.js');
const typeDefs = require('./schema.js');
const resolvers = require('./resolvers.js');
const {firebaseApp}=require("../helpers/firebase");
Expand All @@ -22,7 +24,9 @@ const dataSources = () => ({
EventAPI: new EventAPI(),
VenueAPI: new VenueAPI(),
AccessLevelAPI: new AccessLevelAPI(),
StoryAPI:new StoryAPI()
StoryAPI:new StoryAPI(),
CourseAPI: new CourseAPI(),
TimetableAPI: new TimetableAPI(),
});

const server = new ApolloServer({
Expand Down
36 changes: 36 additions & 0 deletions sources/apollo/timetables/timetable.datasources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint no-useless-constructor: "off", class-methods-use-this: "off" */

const TimetableModel = require('./timetable.model.js')
const { DataSource } = require('apollo-datasource');

class TimetableAPI extends DataSource {
constructor() {
super();
}
// eslint-disable-next-line no-empty-function
initialize(_) {}

getTimetableById(id) {
return TimetableModel.findById(id);
}

getTimetableByIdentifier(identifier) {
const regex = new RegExp(identifier,'u')
return TimetableModel.find({ "identifier" : { $regex: regex, $options: 'i' } });
}

addTimetable(timetable, userId){
let slotInfo =[]
for (const slotInfoElement of timetable.slotInfo){
slotInfo.push(slotInfoElement);
}
const timetableObject = new TimetableModel({
user: userId,
identifier:timetable.identifier,
slotInfo,
});
return timetableObject.save();
}
}

module.exports = TimetableAPI;
85 changes: 85 additions & 0 deletions sources/apollo/timetables/timetable.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// TODO: Update CBy and UBy to make it non-nullabe by design
// TODO: Add Professor

const { Schema, model } = require('mongoose');

const timetableSchema = new Schema(
{
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
identifier: {
type: String,
required: true,
trim: true,
},
slotInfo: [{
name: {
type: String, // Put slot name TA1 TA2 etc here. Not directly used now. May be useful later
required: true,
trim: true,
},
course: {
type: Schema.Types.ObjectId,
ref: 'Course',
required: true,
},
startTime: {
hours:{
type: Number,
required: true,
min: 0,
max: 23
},
minutes:{
type: Number,
required: true,
min: 0,
max: 59
},
},
duration:{
type: Number, // Units in minutes
required: true,
min: 0,
},
day: {
type: Number, // 1-Monday, 5-Friday
required: true,
max: 5,
min: 1
}
}],
expiry: {
type: Boolean,
required: true,
default: false,
},
schemaVersion: {
type: Number,
required: true,
default: 1,
min: 1,
},
createdBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: false,
default: null,
},
updatedBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: false,
default: null,
},

},
{
timestamps: true,
},
);

module.exports = model('Timetable', timetableSchema);
28 changes: 28 additions & 0 deletions sources/apollo/timetables/timetable.resolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/** @format */
/*eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }]*/
const queries = {
timetableById: (_, args, { dataSources }, __) => dataSources.TimetableAPI.getTimetableById(args.id),

timetableByIdentifier: (_, args, { dataSources }, __) => dataSources.TimetableAPI.getTimetableByIdentifier(args.identifier)
};

const mutations = {
addTimetable: (_, {timetable}, { dataSources }, __) => dataSources.TimetableAPI.addTimetable(timetable, "6009a59c3dae9456bce4a8f9"),
};

const fieldResolvers = {
Timetable: {
slotInfo: (parent, _, { dataSources }, __) => {
const {slotInfo}=parent;
const ResolvedCourses=slotInfo.map(async slot => {
// eslint-disable-next-line require-atomic-updates
slot.course= await dataSources.CourseAPI.getCourseById(slot.course)
return slot
})
return ResolvedCourses
},
user: (parent, _, { dataSources }, __) => dataSources.UserAPI.getUserById(parent.user)
}
};
//
module.exports = { queries, mutations, fieldResolvers};
Loading