This page outlines significant architectural decisions at a high level.  This does not aim
to go into detail about the individual client and server projects but rather the significant
top-level design choices common to both.

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

# Architectural Tiers
As a standard web application, the client and server have been split up into two architectural
tiers that each have several layers within them.  Each of these tiers are discussed more within
their respective pages under the Code Architecture and Design section of the wiki.

![Domain-Model.png](./images/architecture_diagram.png)

Below are some of the advantages of seperating the client and the server into two seperate
projects.
- The client can be configured to run independently in a development environment allowing us
  to make use of tools like the ones that come with create-react-app to make development smoother.
- A custom build cycle with webpack can be used to make the client application as efficient as
  possible (again, handled by create-react-app unless it is ejected).
- Cypress tests do not need to initialize the entire API server (end-to-end tests do).
- Integration / API tests can be created without needing to worry about the client side.

For more resources on why this type of architecture suites modern Node.JS applicaitons, see
the [webpack documentation](https://webpack.js.org/concepts/).

## Serving the Client
The client is a single page web application and routing the user to different pages is
handled by [react-router](https://reactrouter.com/web/guides/quick-start).  This means
that all requests to the server must serve up the single page adn react-router will
handle determining which one to display.

This is conflicting with the idea of serving an API from the same server however
because we cannot both fulfil the API request and serve the single page.  To solve this
issue, express allows the use of [routers](http://expressjs.com/en/api.html#router) which
gives us the ability to emulate an entire express server either on a subdomain, or from
a path prefix like `fitrskills.com/api/...`.  All requests to this group of routes will
be handled by the API server abstraction while all others will be handled by the client
server abstraction.

It is best to learn by example, so if this is confusing, reference the three files
`app.js`, `api.js`, and `client.js` in `/server/src` to see this interaction play out.
If at any point the app can no longer be single paged, all additional routes can be
defined in `client.js` without fear of breaking the API.

## API Philosophy
In general, the API is meant to emulate RESTful APIs as much as possible, but there are
some exceptions to this where stateful behavior is the best solution.  This API is meant
to be private, if a public API is ever created it is highly recommended to create another
express abstraction similar to `api.js` and `client.js` to handle such an API.

The API uses cookies and session state to store user's information so that we can customize
the data that is sent back to the client.

We currently also use cookies for authentication since that is the default for
[passport](http://www.passportjs.org/docs/).  This may be suited fine, but a public
API will likely require an implementation of OAuth2.0 which passport also supports.

As a RESTful API, it is important to define the uses for the various HTTP methods.
All of these requests have access to the session state although it should only be used
for storing a reference to user specific data such as their profile.

| Method | Description
|--------|-------------
| GET    | No database updates are caused.
| POST   | New database entries are created.
| PUT    | Currently not used.
| PATCH  | Database entries are updated.
| DELETE | Database entries are removed.

Some further considerations
- One request should not perform multiple duties (i.e. create and update).
- POST, PATCH, and DELETE should simply return a status and in most cases not data.
- Multiple methods can and often should be present on the same path (i.e. POST & PATCH `/profile`)
- Query parameters are typically preferred over path parameters

Note: Our team did not have this well-defined at the start of the project so if there are
discrepancies, they should be fixed.

# Architecturally Significant Requirements
This application has not had much time to develop and therefor the architecturally significant
requirements are sparse.

#### JobSeeker, Employer, Educator
In order to facilitate all three roles, the mongoose schema maintained one list of user credentials
but split their profiles into different types.  This allows us to store different information on a
user's profile based on the types of interaction they will have with the website.

#### Skills
The core of this website revolves around skills, so it is important to have a robust architecture
around these skills.  Each skill is represented as an object in the database and is treated as such
in the frontend as well.  This allows us to keep a list of skills along with more detailed information
about them to ensure there is no confusion.

#### Organizations
Both educators and employers are assigned to organizations.  An organization itself is independent
from any one account, but multiple accounts can be associated with the same organization.  This
allows for flexibility when it comes to who should have permissions to add, edit, or remove courses
and job postings.

# Security Considerations
Members of the previous team have not been experts in security and there likely will need to be
a security audit before the application goes live.

We have however kept the following considerations in the back of our mind and done our best to
mitigate attacks.

- Password Hashing: We use [passport-local-mongoose]() for this.
- No hardcoded credentials: We make use of environment variables
- Path Traversal
- Mongoose prevents SQL injection

It is the controller layer on the server that is responsible for ensuring sensitive data is not
leaked from the server as well as ensuring nefarious data scrubbed.  Our general philosophy is
to use as many third party libraries that are trusted in any situations where security may be
a concern.

Some security considerations we have thought about but have yet to actively mitigate

- CSRF
- XSS
