Skip to content

Technical Specification

Dan Prince edited this page Aug 29, 2016 · 3 revisions

Technical Specification

Here's the work in progress version of the Technical Specification for Orca.

Prototype Review

NoSQL

The document store model is not a good fit for this project. There are too many relationships between users, students, staff and competencies. This makes data fetching very complicated as UI components start to manage multiple concerns in terms of IDs. The data should be remodeled for a relational database.

CouchDB

Only administrators can read from the users database, meaning that students and staff must live across multiple databases. Their "user" accounts live in the users table, along with their role, password and id. Then their "application" accounts are stored in supplementary application databases. This means that adding staff/students is a multi step process and removing them will require database triggers.

CouchDB's revisioning system would allow the application to warn users about document conflicts, but for the purposes of this application, that's probably not necessary.

CouchDB's user management system worked well for the prototype, but going forward it will be necessary to use finer grained user permissions, allowing the platform to denote tables as read only for certain user roles.

PouchDB

Using CouchDB's HTTP API with PouchDB meant that the process of fetching data was very straightforward and allowed the system to easily be turned into an offline mobile/desktop app that instead wrote data into IndexedDB, then fully replicated to a remote database when the network was restored.

React

React has been a reliable technology for building the user interface and should be used to continue development as the project progresses. Using React with the Redux architecture has allowed the codebase to establish a clear divide between components that fetch data or talk to the store, from components that simply render a presentational layer.

Aphrodite

Keeping the styles in JavaScript has been a large success and the end result is an application whose styles are easy to locate, maintain and reuse. The architectural decision to separate global style variables, global stylesheets and component local styles was key to this success.

One identified drawback of Aphrodite is that it always tries to inject the style tag into the DOM. When running under node, this will throw an exception. This means all tests need to expose a global DOM object with a library like JSDOM.

Create React App

Using the official React project scaffolder helped development start quickly and with minimal configuration. It provides no test configuration out of the box, but the development and production build setup made it trivially easy to get started on the project and then finally to create a production ready build for deployment.

Enzyme + Tape

Unit tests have been written in Enzyme and run under Tape. The Enzyme API could still be improved, but its still considerably better than trying to write tests using React's own testing utils.

Tape continues to be a reliable test runner for Node.

Docker

TODO docker review

Data Modeling

Upon reflection, there is a real need to model the following types of data.

Users

Users can be isolated and stored in a dedicated table which will handle user authentication and user roles.

       Users
      /     \
Students   Staff
           /    \
      Mentors  Tutors

The hierarchy here is only for description, as student, mentor and tutor will all be defined as individual and not mutually exclusive roles.

Here is a suggested format for user storage:

{ id: (autogenerated),
  first_name: 'First',
  last_name: 'Last',
  password: '',
  salt: '',
  roles: ['student' | 'mentor' | 'tutor'],
  year: 0 }

Competencies

Like in the prototype the competency definitions will be isolated and stored in their own table.

{ id: (autogenerated),
  name: 'Competency Name',
  year: 1,
  learning_outcomes: [(outcome_id), ...] }

Going forward with a relational model means the outcome definitions can be stored in their own tables.

Learning Outcomes

The outcomes can be extracted from competencies and stored in their own tables.

{ id: (autogenerated),
  name: 'Outcome Name',
  progress_points: [] }

Outcome Progress

{ id: (autogenerated),
  student: (studentId),
  learningOutcome: (learningOutcomeId),
  [NO_PROGRESS | PARTIAL_PROGRESS | COMPLETE, ... ] }

Outcome Review

{ id: (autogenerated),
  student: (studentId),
  learningOutcome: (learningOutcomeId),
  [false | true, ... ] }

Outcome Notes

Notes can be extracted from student outcomes.

{ id: (autogenerated),
  student: (studentId),
  learningOutcome: (learningOutcomeId),
  from: (staffId),
  text: 'Progress comment',
  date: new Date() }

Data Fetching

Rather than trying to manage all data fetching at the client side, there should be a server proxy before the database that can intercept either HTTP requests or GraphQL fragments.

Continuous Integration

todo Continue with CircleCI

Deployments

todo Docker plans

Hosting

Client

Server