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?