alpha-version-dce-check-in-api
Version:
API for taking attendance and checking people in.
187 lines (165 loc) • 5.92 kB
text/typescript
// Import ejs
import ejs from 'ejs';
// Import dce-live-grouper
import {
GrouperRequest,
getGroupAssignment,
} from 'dce-live-grouper';
// Import dce-reactkit
import { genRouteHandler, ParamType } from '../../../../dce-reactkit';
// Import types
import Router from '../../../types/Router';
// Import shared types
import AssignToGroups from '../../../shared/types/AssignToGroups';
import AttendanceEntry from '../../../shared/types/AttendanceEntry';
import GetCourseEvent from '../../../shared/types/GetCourseEvent';
import RecordAttendanceFunction from '../../../shared/types/RecordAttendanceFunction';
import AttendanceMethod from '../../../shared/types/AttendanceMethod';
import ErrorCode from '../../../shared/types/ErrorCode';
// Import shared helpers
import genOccurrenceId from '../../../shared/helpers/genOccurrenceId';
import getTimeInfoInET from '../../../shared/helpers/getTimeInfoInET';
import toStringMMDDYY from '../../../shared/helpers/toStringMMDDYY';
import createOccurrence from '../../../shared/helpers/createOccurrence';
import findOccurrence from '../../../shared/helpers/findOccurrence';
// Import template
import checkInEJSTemplate from './checkInEJSTemplate';
/**
* Main entrypoint for check-in, for login and attendance.
* @author Benedikt Arnarsson
* @author Gabe Abrams
*/
const addCheckInPageRoute = (
router: Router,
recordAttendance: RecordAttendanceFunction,
getCourseEvent: GetCourseEvent,
) => {
router.get(
'/checkin/:ihid',
genRouteHandler({
paramTypes: {
ihid: ParamType.String,
},
handler: async ({ params, send, renderErrorPage }) => {
// Destructure params
const {
ihid,
courseId,
userId,
userFirstName,
userLastName,
isLearner,
} = params;
// Check the user in
try {
// Create basic occurrence info
const {
day,
month,
year,
} = getTimeInfoInET();
const occurrenceBasicInfo = {
courseId,
ihid,
day,
month,
year,
};
// Generate occurrence id
const occurrenceId = genOccurrenceId(occurrenceBasicInfo);
// Find occurrence
let occurrence = await findOccurrence(occurrenceId);
// If no occurrence, create one if possible
if (!occurrence) {
// Get course event
const event = await getCourseEvent({
courseId,
ihid,
requireNotArchived: true,
});
// Event not found
if (!event) {
// Cannot create occurrence because not held in person
return renderErrorPage({
title: 'Could not find event',
description: 'Could not find event. Please double-check your URL or contact your instructor to set it up.',
code: ErrorCode.EventNotFound,
});
}
// Event is not held in person
if (!event.inPersonConfig) {
// Cannot create occurrence because not held in person
return renderErrorPage({
title: 'Event Not Held In Person',
description: 'This event is not held in person, so you cannot check in. Please contact your instructor if you think this is wrong.',
code: ErrorCode.EventNotHeldInPerson,
});
}
// Occurrence cannot be created by a student
if (event.inPersonConfig.assignToGroups !== AssignToGroups.Never) {
return renderErrorPage({
title: 'Event Not Started Yet',
description: 'This event has not started yet, so you cannot check in. Please wait for your instructor to initialize check in.',
code: ErrorCode.OccurrenceNotSetUpToday,
});
}
// Student *can* create the occurrence themselves
occurrence = {
...occurrenceBasicInfo,
grouperEnabled: false,
};
await createOccurrence(occurrence);
}
// Handle grouping
let groupNum: number | undefined;
if (occurrence.grouperEnabled) {
// Create grouper request
const mmddyyStr = toStringMMDDYY({
day,
month,
year,
});
const grouperRequest: GrouperRequest = {
courseId,
eventId: `${ihid}-O${mmddyyStr}`,
studentId: userId,
};
// Run grouping algorithm
const groupAssignment = await getGroupAssignment(grouperRequest);
groupNum = groupAssignment.groupNum;
}
// Write attendance entry
const attendanceEntry: AttendanceEntry = {
userId,
userFirstName,
userLastName,
courseId,
ihid,
isLearner,
method: AttendanceMethod.InPerson,
groupNum,
};
await recordAttendance(attendanceEntry);
// Render check in results page
const page = ejs.render(
checkInEJSTemplate,
{
userFirstName,
groupNum,
},
);
return send(page);
} catch (err) {
// eslint-disable-next-line no-console
console.log('Error:', err);
return renderErrorPage({
title: 'An Unknown Error Occurred',
description: 'We couldn\'t check you in because an unknown error occurred. Try again. If the issue persists, contact your instructor.',
code: ErrorCode.UnknownCheckInError,
});
}
},
}),
);
};
export default addCheckInPageRoute;