Codebase Overview

This document gives a quick overview of the codebase. Truly understanding the code will require reading the code itself directly, but this will point you in the right direction.

API Overview

This section gives a brief outline of the backend rails API codebase and how it differs from standard rails applications.

Rails

The codebase is primarily a Rails application, however it is used exclusively as an API, and not as a full stack webapp. To quickly give an overview of normal rails applications, they consist of

  • Models - Ruby representation of a db table

  • Controllers - Classes that can be thought of as a middleman between Models and Views, generally 1:1 with a REST resource. They are the layer that enables input validation and querying logic.

  • Views - Ruby code to generate json representations of resources for the API.

  • Migrations - Small incremental changes to database, such that the state of the database at any point of the codebases history can be recreated.

  • Jobs - The background processing scripts for rails apps to defer processing outside of sequential request.

  • Rake Tasks - normally used for data modification or miscellaneous semi-regular operations

Apart from the above, the mustard api does not differ dramatically between most rails applications. It does however extend the pattern in a few ways.

Services

In rails applications, you often have the issue of where to put the business logic. Some Rails shops like to take the “Fat Model” approach (putting the business logic in the model), as it is the most reusable and least frowned upon compared to creating “Fat Views” or “Fat Controllers”. The mustard app instead extends the MVC pattern by adding services as an intermediary between controllers and models to create reusable business logic. As such, you will often see controllers interfacing with Services rather than directly interacting with models when the logic is not trivial.

Gems

The mustard app has forked a few gems, imported them into our project. Rather than managing the dependency externally (it’s open source development had stopped), we just created a directory exclusively for them for simplicity. Our backend stack is a monolith, so complicating the dependency structure was unneeded.

Scheduler

Rather than running cron jobs, we use Sidekiq scheduler to run some scripts regularly. It’s config can be found in the config directory, and it’s contents are self-explanatory.

Routes

The API is sectioned off into different conceptual chunks by domain. Ruby modules are used to aid in illustrating this concept. This is largely similar to how the database is structured, where there are a few key models that have many sub-models beneath them. The same is mimicked throughout the api code, where the key routes are

  • api - routes only available to authenticated frontend

  • auth - routes built for authentication and general auth resources

  • guest - routes for anonymous or unauthenticated users

  • my - routes for personal account details

  • panel - routes for admins

  • widget - routes for the embeddable widget feature

Models

Similar to the above, modules are used in our Rails models to mimic a parent model with sub-models beneath them. The key models are

  • Guest - routes for anonymous viewing/searching of candidate profiles

  • Organisation - REST resources related to organisation

  • Payment - REST resources related to stripe integration

  • Person - REST resources for self-serve candidate features

  • Report - Resources for candidate activity reporting

  • Utility - Admin resources

Frontend Overview

The Mustard app was developed using Angular (from version 2 up to 10), TypeScript, Sass and HTML. The main dependencies of this project are:

  • algoliasearch - Used for natural search on candidates page and location filter

  • ngx-bootstrap - Used across many modules to implement bootstrap components like modal, datepicker, tabs, collapse and others

  • ngx-monaco-editor - Code editor on Custom Fields page and Custom CSS

  • ngx-owl-carousel-o - Used on candidates cards experience and education

  • ngx-quill - HTML editor on agreements page and profile

  • ngx-toastr - Used for notifications across the app

Structure

The Angular app was developed using the Lazy Loading strategy where each folder represents a feature module with the exception of shared, core and static. Some of these features have other sub-modules that are also Lazy loaded, this strategy makes the app faster on the first load, requesting from the server only the files needed for that page.

SharedModule

This module contains components used across the features module split into smaller modules. They can be important as a whole or on a module by module basis. For example, the auth module only imports the UiCoreModule from the shared module. This module also contains all the directives, pipes, layouts and interfaces of the Angular App.

CoreModule

This module is imported directly to the app module, being one of the first one's to be loaded. This module contains all the guards used on the app, API services used across many modules and singleton services.

Static

This module contains static pages like Not Found, Access denied, Terms and Conditions and etc.

Last updated

Was this helpful?