######################### Developer Guide ######################### This document focuses frontend and backend development of Pavilion project and gives information about Pavilion Tech Stack. *************************************** Frontend *************************************** Requirements ============ * `Node.js `_. (>= 10.13.0, except for v13) (Windows Build Tools for Windows systems) * `Yarn `_. Clone Repository ================ .. code-block:: rst git clone https://github.com/doganbros/pavilion cd pavilion Install dependencies ==================== .. code-block:: rst yarn install Set environment variables into .env file: ========================================= .. code-block:: rst cp .env.example .env Then make changes to the boilerplate provided Setting web server and routing ============================== If Pavilion is installed on your local computer, you will need to add the following line to your hosts file. The hosts file for Unix based system including MacOs is ``/etc/hosts`` where as on Windows, it is ``C:\windows\system32\drivers\etc\hosts``. .. code-block:: rst 127.0.0.1 pavilion.localhost Run project =========== .. code-block:: rst yarn start Try Pavilion ========== * Visit http://pavilion.localhost:3000 (3000 is the default port) and create your super admin user. *************************************** Backend *************************************** Requirements ============ * `Node.js `_. (>= 10.13.0, except for v13) (Windows Build Tools for Windows systems) * `Yarn `_. * `NestCli `_. * `Postgress `_. First steps are same with fronted setup. Create Postgres database ======================== Please follow the steps below to get a development Postgres server running. The easiest way to use `docker `_. If you have running Postgres database server you can skip these steps and simply create an Pavilion database. * Make sure you have docker installed on your computer. If you do not have docker already on your computer, Go to https://www.docker.com/get-started, choose your platform and click download. Follow the simple steps to get docker installed on your computer. * Open your terminal (command prompt or preferably powershell on windows). * Enter the command .. code-block:: rst docker run --name pavilion-postgres-dev -e POSTGRES_PASSWORD=YOUR_DB_PASSWORD -p 5432:5432 -d postgres * Postgres docker image will be downloaded and Postgres Docker container with the name pavilion-postgres-dev will up and serve from port 5432 after this command. * To connect your Postgres database. .. code-block:: rst docker exec -it pavilion-postgres-dev psql -U postgres * To create your Pavilion database. .. code-block:: rst CREATE DATABASE pavilion; * Update your ``.env`` file with ``YOUR_DB_PASSWORD`` . * Run ``\q`` to quit from Psql and Docker container. Run project =========== To run backend server in production .. code-block:: rst yarn start:server To run backend server in development .. code-block:: rst yarn start:server:dev API Testing =========== Visit http://pavilion.localhost:8000/swagger/ to try out some backend APIs. ************* Software Spec ************* Frontend Features ================= - `Typescript `__ (Strict Mode) - ESNext - `Airbnb Coding Style Guide `__ - `Prettier `__ - `eslint `__ - `yarn `__ is used for package management - `React `__ is the main framework (with hooks) - `React Router `__ is used for client side routing - `Redux `__ is used for managing application state - `Grommet `__ is the main css framework Backend Features ================ - `Typescript `__ (Strict Mode) - `Airbnb Coding Style Guide `__ - ESNext - CORS enabled - `yarn `__ for package management - `Handlebars `__ for rendering email templates - `NestJS `__ is the main framework - `Postgresql `__ is the database used - `TypeORM `__ is the database ORM used - `Class Validator `__ is used to validate request body. - `helmet `__ is used to set http headers correctly. - `dotenv `__ is used to load .env variables - `compression `__ - `eslint `__ - `morgan `__ - `Swagger `__ - Monitoring with `pm2 `__ Open Source Technologies used ----------------------------- - `Jitsi `__ Requirements ============ - `Node.js `__ (>= 10.13.0, except for v13) - `Yarn `__ Glossary ======== - 🏠 represents client side - πŸ–₯️ represents server side Architecture ------------ This is a single page web application, that is it handles routing at the client-side without the need to refresh the entire page. All http requests are done using ``Asynchronous Javascript and XML (AJAX)``. The data exchange format used between this app and the server is ``JSON``. Programming Languages --------------------- `HTML `__ 🏠 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``HTML`` is rarely used in this app. It is primarily used to setup the main index file that is responsible for loading the main javasript of the app. It loads the css and display the initial title of the app. `TypeScript `__ 🏠πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This app uses no ``Javascript`` (Although it compiles to javascript). ``Typescript`` is the main programming language used on the server and for building the user interface. Frameworks and Libraries ------------------------ `NestJS `__ πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nestjs is a progressive Node.js framework for building efficient, reliable and scalable server-side applications. It works well with typescript and follows the `SOLID `__ principle `TypeORM `__ πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TypeORM is a NodeJS database ORM that supports the latest JavaScript features and provide additional features that helps in developing any kind of application that uses databases - from small applications with a few tables to large scale enterprise applications with multiple databases. It works well with typescript. `OpenAPI (Swagger) `__ πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The OpenAPI specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated module which allows generating such a specification by leveraging decorators. `Handlebars `__ πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Handlebars is used to render email templates before they are sent to clients. `SendGrid `__ πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SendGrid is the main service used for sending emails. `Class Validator `__ πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Allows use of decorator and non-decorator based validation. Internally uses validator.js to perform validation. `Axios `__ 🏠πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``Axios`` is a promise based HTTP client used in this app. All AJAX requests are handled with ``axios``. Their interceptors really help to avoid redundancy in most part of the app. `SCSS `__ 🏠 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This app uses no ``CSS`` (Although it compiles to css in the long run). ``SCSS`` is rearely used in this app. It is used to style a large portion of the app. ``SCSS Modules`` is recommended if ``SCSS`` is used. ``node-sass`` is the library responsible for compiling the app’s ``scss`` to ``css`` `React `__ 🏠 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This app uses the latest version of ``React`` Framework (Library) in collaboration with ``Typescript``. ``JavaScript XML`` is used to develop all the components. **Only Functional Components** are allowed for writing all React Components. `Grommet `__ 🏠 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Grommet is a ``React styled-component`` library that helps in building responsive and accessible mobile-first projects for the web. Since this framework provides lots of styled-components, writing ``scss`` is often not required at all. Developers are required to use most of the features of Grommet without writing lots of ``scss`` . `React Router DOM `__ 🏠 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``React Router`` (Its DOM binding ``React Router DOM``) is the library used to for handling all the client side routing of this app. **Note** that instead of using the library’s main ``Link`` and ``NavLink`` components, AnchorLink and NavLink are used respectively. This is to make it compatible with the Grommet library. To navigate to other paths of the app inside a component, the ``useHistory`` hook is used. Routing done in other parts of the app app (especially in a Redux action) uses the ``appHistory`` helper function insead. `Redux `__ 🏠 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``Redux`` is a predictable state Container for Javascript (Typescript) Apps. This is the main state management library used in the app. Mostly states that are shared across multiple components of the app use redux. Also all network-related states are handled here. ``react-redux`` is the library that helps in binding redux to react. ``redux-thunk`` provides the redux middleware that helps the app to deal with asynchronous dispatches in redux actions. `React-i18next `__ 🏠 ``React-i18next`` is a powerful internationalization framework for React / React Native which is based on i18next. Our goal is to support as many languages as possible with the help of this framework and community. Development Dependencies ------------------------ `Eslint `__ 🏠πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``Eslint`` statically analyzes the application code to quickly find problems. It helps in maintaining the usage of Airbnb coding style guide and the similarity of code written by different develops at a time. Run ``yarn analyze`` or ``npm analyze`` to let eslint analyze and report all errors made. If you are using editors like vscode please install the eslint extension to help you in automatically detecting errors. `Prettier `__ 🏠πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``Prettier`` is an opinionated code formatter that helps the app to format the code written to comform to the rules of eslint. Run ``yarn format`` or ``npm format`` to do a quick format of the entire app. `Jest `__ 🏠πŸ–₯️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Jest is a delightful JavaScript Testing Framework with a focus on simplicity. .. _nestjs-1: NestJS πŸ–₯️ --------- While using nestjs at the server-side, One must follow these guidelines. - NestJS pattern must be followed strictly. For example controllers should be used to handle only http requests, services must be used to generate data or communicate with the database, guards must be used for securing routes etc. - controllers and providers should reside in controllers and services directories respectively. - Implement global providers if they are needed only. This will help other developers know from which modules those services are imported from. Example authentication and exceptions would be needed in the entire application but zone service wouldn’t. - the ``@IsAuthenticated()`` decorator should be used to validate the current user’s token. Also permissions could be passed in as paremeters if they are needed. - Document the controllers written extensively (using decorators provided by Nestjs for OpenAPI). This helps other developers to make requests very easily without reading the source code. - The built in NestJS exceptions must be used accross the entire application. The first paramter must be a message about the error. And the second parameter must be an error code. For example while generating an error for invalid bearer authentication token, the example below is used. .. code:: ts throw new UnauthorizedException( 'You not authorized to use this route', 'NOT_SIGNED_IN', ); .. _typeorm-1: TypeORM πŸ–₯️ ---------- While using TypeORM at the server-side, One must follow these guidelines. - The models designed must be relational. That means you must use ``OneToOne``, ``ManyToOne``, ``OneToMany`` or ``ManyToMany`` relation when it is necessary. - When models, fields, column, etc. are added a migration script must be written in respect of that. This is because we are not using syncronization as it not good for production. **Note** that nestjs will run pending migrations when the application is booted automatically. Guards In This Application and their usage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This section introduces the main guards used in this application - .. rubric:: AuthGuard :name: authguard The AuthGuard validates the current bearer token passed to the server when making requests. It sets the payload of the user to ``req.user``. It also thows an ``UnauthorizedException`` exception when the token is invalid. - .. rubric:: UserZoneGuard :name: userzoneguard The UserZoneGuard validates the current user’s authorization to the zone that he/she is requesting. It sets the user zone to ``req.userZone``. Other permissions can be passed in using the ``SetMetadata`` decorator. It also throws an ``NotFoundException`` exception when the user is not authorized. Pipes in this application and their usage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This section introduces the main pipes used in this application - .. rubric:: ParseTokenPipe :name: parsetokenpipe The ParseTokenPipe is used to parse a JWT. If it succeeds it passes the payload to the parameter. Otherwise it will throw an ``UnauthorizedException``. Decorators in this application and their usage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This section introduces the main decorators used in this application - .. rubric:: IsAuthenticated :name: isauthenticated The IsAuthenticated decorator wraps over the AuthGuard to avoid writing lots of boilerplates while passing permissions to the AuthGuard. - .. rubric:: UserZoneRole :name: userzonerole The UserZoneRole decorator wraps over the UserZoneGuard to avoid writing lots of boilerplates while passing permissions to the it. It also extends the IsAuthenticated decorators so if you do not need to specify it while using it on a route. - .. rubric:: UserChannelRole :name: userchannelrole The UserZoneRole decorator wraps over the UserChannelGuard to avoid writing lots of boilerplates while passing permissions to the it. It also extends the IsAuthenticated decorators so if you do not need to specify it while using it on a route. - .. rubric:: CurrentUser :name: currentuser The CurrentUser decorator is helper to retrieve the current user’s jwt payload - .. rubric:: CurrentUserZone :name: currentuserzone The CurrentUserZone decorator is helper to retrieve the current user zone. Notice that it zoneId or userZoneId must be set as params in order to retrieve this. - .. rubric:: CurrentUserChannel :name: currentuserchannel The CurrentUserChannel decorator is helper to retrieve the current user channel. Notice that it channelId or userChannelId must be set as params in order to retrieve this. Middlewares Used in this application ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This section introduces the main middlewares used in this application. - .. rubric:: PaginationMiddleware :name: paginationmiddleware The PaginationMiddleware parses all get requests’ pagination query paramters. All get requests pass through this middleware. This means that, the pagination query parameters ``req.query.limit`` and ``req.query.skip`` are passed to controllers automatically (Global middleware for get requests). It can in turn be used in paginating records. When no values for limit and skip query parameters are passed by the user, limit is set to a default of 30 and skip is also set to a default of 0. Limit cannot be greater that 100. The type ``PaginationQuery`` can help in intellisense. Authentication -------------- This app interacts with a stateless http server. Authentication is realized by sending a `JSON Web Token `__ (By the way this is one of my favorite technologies) to the server. The steps for authenticating users are listed below. 1. When it is the first time the user is visiting the app or the returning user is not authenticated, React Router will redirect the user to the login page. 2. The User will either login or create a new account 3. The app sends the authentication information to the server 4. If the server successfully authenticates the user, a json web access token and its refresh token is created on the server and sent as an http only cookie to the client 5. By default the access token only lasts an hour. After this if the refresh token is still valid, the server will generate a new access and refresh tokens to the client 6. In subsequent requests, the app will send the access token stored in the cookies to the server to identify the user making the request. 7. If the token expires or becomes invalid the user will automatically be redirected to the login page. Thanks to the ``axios`` response interceptor. 8. If the user returning to the app is already authenticated react router will redirect the user to the main application page. Authentication persistence through subdomains ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since this app allows users to create subdomains, it needs to persist authentication through the main domain and subdomains. This is one of the main reasons why cookies are been used. For cookies to persist authentication through domains and subdomains, the main domain parameter supplied while creating them must be valid. One of the rules for its validity is that it must have at least one dot. Due to this, localhost will not work. Read this `article `__ to learn more. Even though developers can still use localhost but if another subdomain is visited, authentication would be required again. Developers can therefore set a different domain other than localhost in ``/etc/host`` ( or ``C:\Windows\System32\Drivers\etc\hosts`` for windows) file. The domain recommended is octopus.localhost. This is because it allows all subdomains to see the cookie as well. # Application Structure :: β”œβ”€β”€ README.md β”œβ”€β”€ SOFTWARE-SPEC.md β”œβ”€β”€ appspec.yml β”œβ”€β”€ package-lock.json β”œβ”€β”€ package.json β”œβ”€β”€ scripts β”‚Β Β  β”œβ”€β”€ after_install.sh β”‚Β Β  β”œβ”€β”€ before_install.sh β”‚Β Β  └── start.sh β”œβ”€β”€ server β”‚ β”œβ”€β”€ README.md β”‚ β”œβ”€β”€ dist β”‚ β”œβ”€β”€ entities β”‚ β”‚ β”œβ”€β”€ Channel.entity.ts β”‚ β”‚ β”œβ”€β”€ Invitation.entity.ts β”‚ β”‚ β”œβ”€β”€ Post.entity.ts β”‚ β”‚ β”œβ”€β”€ User.entity.ts β”‚ β”‚ β”œβ”€β”€ UserChannel.entity.ts β”‚ β”‚ β”œβ”€β”€ UserChannelPermission.entity.ts β”‚ β”‚ β”œβ”€β”€ UserZone.entity.ts β”‚ β”‚ β”œβ”€β”€ UserZonePermission.entity.ts β”‚ β”‚ β”œβ”€β”€ Zone.entity.ts β”‚ β”‚ β”œβ”€β”€ base β”‚ β”‚ β”œβ”€β”€ data β”‚ β”‚ └── repositories β”‚ β”œβ”€β”€ helpers β”‚ β”‚ β”œβ”€β”€ jwt.ts β”‚ β”‚ └── utils.ts β”‚ β”œβ”€β”€ migrations β”‚ β”‚ └── 1625561314952-InitialMigration.ts β”‚ β”œβ”€β”€ ormconfig.ts β”‚ β”œβ”€β”€ src β”‚ β”‚ β”œβ”€β”€ app.module.ts β”‚ β”‚ β”œβ”€β”€ auth β”‚ β”‚ β”œβ”€β”€ mail β”‚ β”‚ β”œβ”€β”€ main.ts β”‚ β”‚ β”œβ”€β”€ typeorm-exception.filter.ts β”‚ β”‚ β”œβ”€β”€ utils β”‚ β”‚ β”œβ”€β”€ views β”‚ β”‚ └── zone β”‚ β”œβ”€β”€ test β”‚ β”‚ β”œβ”€β”€ app.e2e-spec.d.ts β”‚ β”‚ β”œβ”€β”€ app.e2e-spec.js β”‚ β”‚ β”œβ”€β”€ app.e2e-spec.js.map β”‚ β”‚ β”œβ”€β”€ app.e2e-spec.ts β”‚ β”‚ └── jest-e2e.json β”‚ β”œβ”€β”€ tsconfig.build.json β”‚ β”œβ”€β”€ tsconfig.json β”‚ β”œβ”€β”€ tsconfig.tsbuildinfo β”‚ └── types β”‚ β”œβ”€β”€ Post.ts β”‚ β”œβ”€β”€ PaginationQuery.ts β”‚ β”œβ”€β”€ UserPayloadRequest.ts β”‚ └── UserZoneRequest.ts β”œβ”€β”€ src β”‚Β Β  β”œβ”€β”€ App.tsx β”‚Β Β  β”œβ”€β”€ assets β”‚Β Β  β”‚Β Β  β”œβ”€β”€ background.png β”‚Β Β  β”‚Β Β  └── logo.png β”‚Β Β  β”œβ”€β”€ components β”‚Β Β  β”‚Β Β  β”œβ”€β”€ layouts β”‚Β Β  β”‚Β Β  └── utils β”‚Β Β  β”œβ”€β”€ config β”œβ”€β”€i18n β”‚ └── [language].json β”‚Β Β  β”‚Β Β  β”œβ”€β”€ app-config.ts β”‚Β Β  β”‚Β Β  └── http.ts β”‚Β Β  β”œβ”€β”€ helpers β”‚Β Β  β”‚Β Β  β”œβ”€β”€ history.ts β”‚Β Β  β”‚Β Β  β”œβ”€β”€ utils.ts β”‚Β Β  β”‚Β Β  └── validators.ts β”‚Β Β  β”œβ”€β”€ hooks β”‚Β Β  β”‚Β Β  └── useTitle.ts β”‚Β Β  β”œβ”€β”€ index.tsx β”‚Β Β  β”œβ”€β”€ layers β”‚Β Β  β”‚Β Β  β”œβ”€β”€ meeting β”‚Β Β  β”‚Β Β  └── zone β”‚Β Β  β”œβ”€β”€ models β”‚Β Β  β”‚Β Β  β”œβ”€β”€ form-submit-event.ts β”‚Β Β  β”‚Β Β  └── response-error.ts β”‚Β Β  β”œβ”€β”€ pages β”‚Β Β  β”‚Β Β  β”œβ”€β”€ Private β”‚Β Β  β”‚Β Β  └── Public β”‚Β Β  β”œβ”€β”€ react-app-env.d.ts β”‚Β Β  β”œβ”€β”€ routes.ts β”‚Β Β  β”œβ”€β”€ scss β”‚Β Β  β”‚Β Β  └── index.scss β”‚Β Β  └── store β”‚Β Β  β”œβ”€β”€ actions β”‚Β Β  β”œβ”€β”€ constants β”‚Β Β  β”œβ”€β”€ reducers β”‚Β Β  β”œβ”€β”€ services β”‚Β Β  β”œβ”€β”€ store.ts β”‚Β Β  └── types └── tsconfig.json - ``README.md`` This is the main readme file of the application - ``package-lock.json`` This is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates. - ``package.json`` Lists all the dependencies, author, version, etc of the app. - ``public`` This is where the main index.html file that loads the react app lives. - ``server`` This is where most backend work is done in this app. - ``dist`` Typescript compiles to this directory. - ``entities`` This is directory hosts all the typeorm model definitions. All typeorm entities must end with ``.entity.ts`` - ``base`` This directory hosts the typeorm models that will be inherited by other models. For example the ``RecordEntity`` defines most of the repeating fields in records such as ``id``, ``createdOn``, ``updatedOn`` etc. - ``data`` This directory hosts the default data used by some entities. - ``helpers`` This directory hosts all the utilities functions of the application. - ``migrations`` This directory hosts all the migration scripts used by typeorm. To create a new migration please use the script ``yarn migration:create``. NestJS automatically runs all pending migrations when it is booted. While creating migrations, typeorm driver must be prefered to raw sql. This helps in migrating to other databases in the future. - ``types`` This directory hosts all the utility typescript types used in the application. - ``test`` This is the directory that hosts all end-to-end testing scripts. - ``src`` This is the directory where most of the work is done. It hosts all the NestJS controllers, modules, services, pipes, guards, middlewares etc. Note that, scripts other than NestJS specific shouldn’t be put here. - ``app.module.ts`` The root module of the application. All other modules are imported into this file. - ``main.ts`` The entry file of the application which uses the core function NestFactory to create a Nest application instance. - ``mail`` This directory hosts the module used for sending mails in this application. To send a mail, a view is created inside the views directory. The ``MailModule`` is imported into the current module and the ``MailService`` is injected into the current service. Using the ``sendMailByView`` method of the mail service emails can be sent using sendgrid. - ``[module_name]`` The src directory hosts all the nestjs modules in this application. To create a new module, a new directory with the same name is created. It is recommended that the nest cli is used to generate modules, controllers, services etc. The nest cli command ``nest g module [module_name]`` generates a new module. This creates a new directory inside the src folder and a new module named ``[module_name].module.ts``. All directories created inside this must not be empty. - ``decorators`` All decorators for this module is created in this directory. - ``dto`` All dtos for this module is created in this directory. A DTO is an object that defines how the data will be sent over the network. This is especially useful in ``POST`` and ``PUT`` requests. The class validator decorators can also help in validating payload fields. All dtos must end with ``.dto.ts``. - ``pipes`` All pipes for this module is created in this directory. Pipes are used to transform input data coming from ``req.body``, ``req.query`` or ``req.params`` etc. All pipes must end with ``.pipe.ts`` - ``guards`` All guards for this module is created in this directory. Guards determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. All guards must end with ``.guard.ts`` - ``interfaces`` All interfaces for this module is created in this directory. **Note**: All interface must be declared using ``class`` but not the ``interface`` keyword. This is because Typescript removes all interfaces when it is compiling to Javascript. All interfaces must end with ``.interface.ts`` - ``exceptions`` All exceptions for this module is created in this directory. Nest comes with a built-in exceptions layer which is responsible for processing all unhandled exceptions across an application. When an exception is not handled by your application code, it is caught by this layer, which then automatically sends an appropriate user-friendly response. All exceptions must end with ``.exception.ts`` - ``controllers`` If multiple controllers are used in this module, it is recommended to put them in the controllers directory. Otherwise there is no need to create this directory for them. All controllers must end with ``.controller.ts`` - ``controllers`` If multiple services are used in this module, it is recommended to put them in the services directory. Otherwise there is no need to create this directory for them. All services must end with ``.service.ts`` ``[module_name].module.ts`` This is the file that all providers, controllers etc of this module are imported into. This is then imported into the ``app.module.ts`` - ``ormconfig.ts`` This is the file that contains all the configuration of the application’s database. It is used by typeorm to create migrations and connect to the database. - ``tsconfig.json`` This is the file that contains the typescript configuration for the server. The configuration used in this app is in strict mode. - ``src`` This is where most frontend work is done in this app. - ``App.tsx`` This is the main component that loads the app routes and run initial scripts (eg. retrieving current user) - ``assets`` This directory contains all the static assests used in the app - ``components`` This directory contains most of the helper components used in the app - ``config`` This directory contains all the configuration files of the app - ``helpers`` This directory contains all the utilities functions of the app - ``hooks`` This directory contains all the general react hooks used in the app - ``index.tsx`` This is the main script and starting point of the app responsible for bootstrapping the react app - ``layers`` This is the directory where layers (modals) used in the app are stored - ``models`` This is the directory where typescript types used accross the entire app are declared. - ``pages`` This is the directory where pages served in the browser are stored - ``Private`` All Privates Pages are stored in this directory. - ``Public`` All Public Pages are stored in this directory. - ``react-app-env.d.ts`` This is a generated file coming with create react app - ``routes.ts`` This is the file where all public and private routes are decalared. All public and private routes live in the publicRoutes and privateRoutes array respectively. Make sure you put the route in the correct context. All private routes require that users are authenticated, otherwise they will be redirected to the login page - ``scss`` The directory that hosts all the scss for the app - ``store`` This is the directory that is used to handle everything to do with the app’s redux store. - ``actions`` All actions of the store are declared in this directory. Every action ends with ``.action.ts``. This is to make all actions easier to search. Also all action functions end with ``Action``. - ``constants`` All constants used in the store is declared in this directory. End all constants with ``.constant.ts``. This is to make all constants easier to search. - ``reducers`` All reducers of the store are declared in this directory. Every reducer ends with ``.reducer.ts``. This is to make all reducers easier to search. - ``services`` All services of the store are declared in this directory. Every service ends with ``.service.ts``. This is to make all services easier to search. The ``http`` helper function must be used to make http requests - ``store.ts`` This is the script that creates the main store of the app. - ``types`` All typescript types of the stored are declared in this directory. Every type file ends with ``.types.ts``. This is to make all types easier to search. - ``tsconfig.json`` This is the file that contains the typescript configuration for the app. The configuration used in this app is strict - ``scripts`` Server run and build commands are included in this folder files for installing requirements and ci cd auto deployment. - ``appspec.js`` file contains scripts files calls for ci cd auto deployment into aws instance