This page discussed the model tier architecture and coupling between model tier objects.

- **Author**: Alex Wilkes <[adw4236@rit.edu](mailto:adw4236@rit.edu)>

# Model Tier Documentation
The model tier of the application takes a much more object oriented approach than most
of the project.  Each domain concept has at least one associated mapping to an object
that contains relevant data and methods.  If needed, this architecture can be converted
to something more functional, see
[Database Migration](https://github.com/FiTRSkills/ForkInTheCode/wiki/Database-Migration-Plan)
for more information on how this can be accomplished.

With the use of mongoose, we are able to easily map each object with a defined schema to
a Mongo or other similar NoSQL database as well as easily retrieve them in JSON fomat.
Mongoose also allows us to easily map static and non-static methods to the objects.

**Recommendation**: All mongoose functions should be encapsulated by the model layer.  At the
moment, this is not the case, but it may be a good idea to ensure no other layers make use of
the mongoose API to better specify these objects and support the database migration plan.

## Dependency Graph
![Model Dependency Graph](./images/models_diagram.png)

The skill is the central concept for this graph.  JobSeekers list skills they have on their
profile, JobPostings list skills they are seeking, and courses list skills that they teach.
JobPostings also have a relationship to courses based on ones they recommend.  When searching
for courses, this relationship should be used to determine the order courses are displayed.

Organizations exist as a pseudo permission system.  This whole concept could have some improvements
but at the moment exists as a 1:1 mapping between the domain and code.
See [Merging User Types](https://github.com/FiTRSkills/ForkInTheCode/wiki/Merging-User-Types)
for more information about how this might be improved.  JobPostings and Courses map to organizations
and any user that is associated with that organization has full permissions to add/edit/delete
job postings or courses depending on their profile type.

The type of user is defined by their profile.  A User contains common information like email
and passwords and acts as a single point for authentication, but the profile itself is what is
checked to give users access to different features.  As mentioned above, a more robust permission
model could eventually replace this structure to streamline types of accounts.

## Object Documentation
This section outlines the data and functionality that exist within each object as well as providing
a closer look at the need and use for each object.  Since the exact schema of these objects are
likely to change, this is kept as more of a general overview, reference the code for the exact
schema and method definitions.

**NOTE**: This is an idealized document and there may be several methods missing from what is
stated.  If the future team agrees with this philosophy the model tier should aim to embrace
this as much as possible, if they disagree, this documentation can be re-written or removed
altogether.

### User
[Passport](http://www.passportjs.org/) and specifically
[Passport Local Mongoose](https://github.com/saintedlama/passport-local-mongoose#readme)
work best when there is a single source of truth for all accounts.  The User object stores all
account credentials as well as what type of account they are, and a reference to the profile
through it's ID.  The type along with the ID can be used in conjunction to look up the exact
user profile associated with the account.

**Data**

- User credentials
- Profile type
- Account statistics (e.g. creation date)

**Functionality**

- Authentication - Through passport local mongoose
- Retrieve profile - Get profile based on type and profile ID

### Profile
This object itself does not exist in code, but represents an abstraction for all types of
profiles together.

### JobSeekerProfile
Contains any information you would expect to find related to a job seeker.  This includes
any statistical information the application would like to collect (such as personal info
to gauge success in reducing hiring bias) as well as professional information the job seeker
would like employers to know.

**Data**

- Personal Info - Protected from employers to reduce hiring bias
- Professional Info - Anything that would go on a resume
- Skills

**Functionality**

- CRUD Single attributes - A set of methods that can be used to update any/all attributes at once
- Add/Edit/Remove Array attributes - Any arrays stored in the profile like skills should have
  their own methods to mutate their values for ease of use.

### EmployerProfile
Stores all information relevant to an individual who has permissions to manage job postings.
At the moment, there is no information present here.

**Data**

- Organization

**Functionality**

- CRUD Organization - Methods to modify the organization

### EducatorProfile
Stores all information relevant to an individual who has permissions to manage courses.
At the moment, there is no information present here.

**Data**

- Organization

**Functionality**

- CRUD Organization - Methods to modify the organization

### Organization
Stores all details related to a single organization.  A single organization may have many
branches and users associated with them.

**Data**

- Organization details - What the organization would want available to job seekers or other
  organizations.
- Location - Will need a more robust [location services](https://github.com/FiTRSkills/ForkInTheCode/wiki/Locations-Services)
  with multiple possible locations including online.  This should ultimately replace or at least
  supplement the job postings location (zipcode) itself.

**Functionality**

- CRUD Single attributes - A set of methods that can be used to update any/all attributes at once
- Add/Edit/Remove Array attributes - Any arrays stored in the profile like skills should have
  their own methods to mutate their values for ease of use.

### JobPosting
Stores all details an employer would want available to a job seeker about an opening they are
trying to fill.

**Data**

- Position Info - Any details related to the type of work
- Organization - The organization this job posting is made by
- Skills - The skills required for the applicant to have
- Courses - Recommendations for courses to acquire the skills required.

**Functionality**

- CRUD Single attributes - A set of methods that can be used to update any/all attributes at once
- Add/Edit/Remove Array attributes - Any arrays stored in the profile like skills should have
  their own methods to mutate their values for ease of use.

### Course
Stores all details an educator would want available to a job seeker or employer about a course
they offer.

**Data**

- Course Info - Any details related to the course offering
- Organization - The organization this course is offered by
- Skills - The skills this course aims to teach

**Functionality**

- CRUD Single attributes - A set of methods that can be used to update any/all attributes at once
- Add/Edit/Remove Array attributes - Any arrays stored in the profile like skills should have
  their own methods to mutate their values for ease of use.

### Skill
Represents a single skill or credential a person could posses. The skill is the most important
concept and is referenced in multiple places throughout the system.

**Data**

- Name - The primary name used to reference a skill
- Description - A detailed report that can be used to understand exactly what a skill is

**Functionality**

- CRUD Single attributes - A set of methods that can be used to update any/all attributes at once
- Add/Edit/Remove Array attributes - Any arrays stored in the profile like skills should have
  their own methods to mutate their values for ease of use.

### SkillHistory
While not labeled on the above diagram, this is meant to track all updates to any skill object
as an audit trail.  This will allow administration to see who is making changes to skills and
prioritize keeping a consistent skill language.

**Data**

- User - A reference to the user that made such a change
- Skill - A reference to the current skill object
- Before - A copy of the skill's values before the change was made
- After - A copy of the skill's values after the change was made

This is a read only collection, so the only functionality that should exist is that which
an administrator would use to rectify the logs.  This would likely be a manual process.
