# Account Everything is keyed off of root accounts. Accounts can be configured in a number of ways, but most configurations are only available on the root account (things like authentication, SIS, js/css embeds). Courses, sub-accounts, logins, etc. will be scoped to the root account. # Users Users are global, and can span across root accounts (although in most cases they won't). Visitors don't log in as users, though, they log in as pseudonyms. Pseudonyms are tied to a specific root account. Visitors log in using a Pseudonym and password, which is then used to retrieve the actual user data. Pseudonyms can either store a hash of the user's password, or if configured on the root account they can authenticate through another service like LDAP or SAML. # Communication Preferences Users can receive notifications for different types of events (if an assignment is graded, if a new announcement is made, etc.). They can specify where and how often they would like those messages sent. A user has multiple CommunicationChannels, each of which are a route for messaging. They can register email, sms, or facebook communication channels and then have certain types of notifications send out immediately, daily, weekly or never to those channels. Each notification type is a Notification record, and a user specifies NotificationPolicy records that state where and how often to send each type of notification. Some notification types also show up on the user's dashboard activity stream (see StreamItems). To send a notification to a user we trigger custom events using the vendor/plugins/broadcast_policy plugin. In an ActiveRecord model you call set_broadcast_policy to do this. BroadcastPolicy retrieves a list of recipients and creates a DelayedNotification record to be handled in the background. The DelayedNotification is then used to build a list of Message records, one per user per specified channel. # StreamItems When we want to send a message to one or more users' dashboards, we create a StreamItem, which is a cached version of the needed data to render the item. This way we can populate the dashboard of a user with only one database lookup. For every affected user we create a StreamItemInstance that ties the StreamItem to the user. To see how items show up in streams check out lib/send_to_stream.rb. # Inbox The inbox is not really an inbox (better name anyone?). It's a place where you can see messages that are probably directed to you. So if someone sends a direct message to you through the inbox tool, or if someone replies to a topic you started, or if someone replies to your reply in a topic, or if someone comments on one of your homework submissions, or if you're a teacher and a student comments on their submission in a course you're teaching, then the message will show up in your inbox. To see how items show up in the inbox check out lib/send_to_inbox.rb # Assignments Assignments probably isn't the best term for it, because it's more than just assignments. This is anything that a teacher wants to show up in their gradebook, so that's assignments, attendance, tests, papers, etc. Every assignment can have a points possible, allow for submitting online, and can be associated with a forum, quiz, etc. Assignments are organized into groups. Every AssignmentGroup can have a weight assigned (so a teacher could say "Papers are worth 50% of the final grade, Tests worth 30%, Homework worth 20%"), and have custom grading rules (i.e. "Drop the lowest 2 scores"). A teacher can also just do straight points-based grading if they want. The gradebook shows all assignments and students in a grid, and by default calculates final grades based only on assignments that have actually been graded. This gives a better feel for a student's progress throughout the semester, instead of just once all the grades have been entered. Students also have access to just their own grades with the same calculations. Students can enter "what-if" grades and see how future grades will affect their final grade. # Files Every course, group, and individual user gets a place to hold files. They can organize them into folders, lock and unlock files for student access, import batches of files as a single zip, etc. The default is a simple javascript uploader, but if flash is enabled then a multi-file uploader is overlaid and used instead. If you have edit priveleges, you can drag a folder to another context and copy its contents without having to re-upload all the files. Files (Attachment is the name of the model) are namespaced by the root account, and if a user uploads a file that matches some other file in the same root account we don't store two copies, we just keep a pointer. This makes it harder for us if we want to delete old files, but keeps storage down. # Wiki Every course and group gets a wiki. They can set edit priveleges to only teachers, or students as well. There's no wiki words, instead there's a WYSIWYG editor and a sidebar with all the links you could possibly want. In fact, every editable page inside of Instructure gets the same sidebar, so it's easy to link from an assignment page to a forum, a file, a wiki page, etc. Wiki pages are accessed by name, and created on demand (/courses/5/pages/new_page would be created if it didn't exist and you went to it). # Quizzes Teachers can build online quizzes for students to take. They can be graded or ungraded. There are a few quiz question types, including multiple choice, true-false, fill-in-the-blank, missing word, short answer, numerical answer, and short essay. A teacher builds a set of questions, assigns each question points, and students can then take the quiz. Questions answers are keyed randomly to prevent cheating, and all grading is done server-side. Quizzes can also include question groups. This is easiest to explain with an example. A teacher could create a group with fifty questions, and then say every student should be given a random selection of five of those fifty questions, worth five points each. Quiz questions are also stored as AssessmentQuestion records. This is so they can be organized into question banks and reused on future quizzes. QuestionBanks can be bookmarked by a teacher, which means they'll be able to add questions from that bank to any course they manage. # Calendar The calendar view shows assignment due dates and calendar events overlaid on a monthly calendar. A user can see all their courses, groups, and personal events overlaid on the same calendar a la Google Calendar. Those with edit priveleges can drag and drop, rename events, etc. A user can subscribe to their calendars using an external tool via the ical feed link on their calendar page. Currently there are no repeating events in the calendar, and no way to import an ical feed into the Instructure calendar. # Forums Every course and group has a discussion forum. Topics include replies, and every reply can have a set of sub-replies, but that's as deep as it goes, no sub-sub-replies. Sub-replies are called 'Side Comments'. Announcements also show up in the forum view for discussion. Teachers can lock topics so they can't be posted to. They can also rearrange the order of topics if they like. # Modules Courses can have modules, which are just collections of different types of content. A module could have some files, some wiki pages, some assignments, etc. Teachers can specify criteria for completing modules, and then specify prerequisites for modules. This lets a teacher block access to some content in the course until the user has, say, gotten a minimum score or viewed a page. # Access Control Account managers can set fine-grained permissions on a per-role basis. Right now the roles they can specify permissions for are Teacher, Student, Ta, Observer and Designer. Access controls are inherited up the chain. If a teacher doesn't define permissions, they are inherited from the department, then the college, then the school. Anywhere along the chain an admin can "lock" a permission, which says, "I don't want anyone down the chain to override my decision for this policy". Account managers can also create different types of account users. They can define as many custom account roles as they like (i.e. sys admins, tech support, etc.) and define what permissions those role types have.