diff --git a/README.md b/README.md
index 890cecc..91c5b4f 100644
--- a/README.md
+++ b/README.md
@@ -1,50 +1,299 @@
-# Maestro
- Maestro
-This is the Dadosfera´s gateway repository, it´s responsable for the communication between frontend application and Dadosfera´s mirosservices.
-## 💻 Requirements
+# Maestro
+Maestro is the Dadosfera's gateway, it's responsible for the communication between the frontend application and Dadosfera's microservices.
-Before you start, make sure you have done the following steps:
+## 🚀 Starting
+These instructions will allow you to get a working copy of the project on your local machine for development and testing purposes.
-* Installed Nodejs version 16.14.2
-* Installed latest NPM version
+### 📋 Requirements
+- [NodeJS v18.3.0 LTS / NPM v8.11](https://nodejs.org/pt-br/download/) (you can opt to use [NVM](https://github.com/nvm-sh/nvm) to easily manage node versions)
+- Request access to AWS Console dev account for **all services** (avoid gradually asking for each needed service. it will slow down your development cycle)
+ - Create your Access Key on the "Security credentials" menu
+ - Set the Access Key on your local development machine
+- Request access to the dev, stg and prd VPNs
+### 🔧 Installation
+- Clone the repository
+ - SSH
+ ```
+ git clone git@github.com:dadosfera/maestro.git
+ ```
+ or
+ - HTTPS
+ ```
+ git clone https://github.com/dadosfera/maestro.git
+ ```
-## 🚀 Installing Maestro
+- Select the correct node version (optional, only if using [NVM](https://github.com/nvm-sh/nvm)):
+ ```sh
+ nvm use
+ ```
-First of all clone the repository:
- * SSH:
-```
-git clone git@github.com:dadosfera/maestro.git
-```
- * HTTPS:
-```
-git clone git@github.com:dadosfera/maestro.git
+- Install the project dependencies:
+ ```sh
+ npm i
+ ```
+
+- Setup the following enviroment variables:
+ ```
+ ENV=
+ DUC_URL=
+ INFACTORY_URL=
+ OTFACTORY_URL=
+ PIFACTORY_URL=
+ SM_OAUTH_PATH=
+ ```
+
+- Start the server:
+ ```sh
+ # dev mode
+ npm run start:dev
+
+ # or in debug mode
+ npm run start:debug
+ ```
+ The service should start successfully.
+
+## Authentication decorators
+Maestro have utilities to ease the user authentication on every controller and route. The following decorators are available:
+
+### `@Authenticated`
+If the user must be authenticated to make request, we can use the `@Authenticated` decorator in the controller or route, as needed.
+
+```ts
+import { Authenticated } from '../../authentication/authentication.decorator';
+
+@Controller('foo')
+@Authenticated()
+class FooController {
+ /* ... */
+
+ @Get('bar')
+ async getBar() {
+ this.logger.info('user is authenticated!');
+
+ return { authenticated: true };
+ }
+}
```
-## Enviroment variables
+```ts
+import { Authenticated } from '../../authentication/authentication.decorator';
-Here is a list of enviroment variables needed in order to run the application correctly.
+@Controller('foo')
+class FooController {
+ /* ... */
-```
-ENV=
-DUC_URL=
-INFACTORY_URL=
-TRFACTORY_URL=
-OTFACTORY_URL=
-PIFACTORY_URL=
-JWT_PRIVATE_KEY=
-AWS_IDENTITY_POOL_ID=
+ @Get('bar')
+ @Authenticated()
+ async getBar() {
+ this.logger.info('user is authenticated!');
+
+ return { authenticated: true };
+ }
+
+ @Post('bar')
+ async postBar() {
+ this.logger.info('user is NOT authenticated!');
+
+ return { authenticated: false };
+ }
+}
```
-## Running Maestro
+### `@RequireAllPermissions`
+This decorator requires that **all permissions** listed are granted to the requesting user.
-In order to run Maestro just run the following command:
+```ts
+import { RequireAllPermissions } from '../../authentication/authentication.decorator';
+import { Permissions } from '../../authentication/permissions.enum';
+
+@Controller('foo')
+class FooController {
+ /* ... */
+
+ @Get('bar')
+ @RequireAllPermissions(Permissions.BAR.MANAGE, Permissions.BAR.CREATE)
+ async getBar() {
+ /* ... */
+ }
+}
```
-npm run start:dev
+
+### `@RequireSomePermission`
+In the following case, the user is required to have **at least one** listed permission.
+
+```ts
+import { RequireSomePermission } from '../../authentication/authentication.decorator';
+import { Permissions } from '../../authentication/permissions.enum';
+
+@Controller('foo')
+@RequireSomePermission(Permissions.FOO.MANAGE, Permissions.FOO.CREATE)
+class FooController {
+ /* ... */
+
+ @Get('bar')
+ async getBar() {
+ /* ... */
+ }
+}
```
-If everything is fine the Maestro will start and be ready to receive HTTP requests
\ No newline at end of file
+
+### `@AuthenticateCondition`
+If a more complicated authentication check needs to be done, we can use the `@AuthenticateCondition` decorator to define it. The custom function must return `true` to authenticate the request.
+
+In the following example:
+- all routes on the `FooController` controller can only be requested from localhost
+- `POST /foo/bar` can only be requested from localhost **and** by users from customer id `111...eef`
+
+```ts
+import { AuthenticateCondition } from '../../authentication/authentication.decorator';
+
+@Controller('foo')
+// allow requests only from localhost
+@AuthenticateCondition((request: Request) => request.ip === '::ffff:127.0.0.1')
+class FooController {
+ /* ... */
+
+ @Get('bar')
+ async getBar() {
+ /* ... */
+ }
+
+ @Post('bar')
+ // allow requests only from a specific customer
+ @AuthenticateCondition((request: Request, user: RequestUser) => user.customer_id === '1113e943-2187-4fdd-9c2c-54338fedaeef')
+ async postBar() {
+ /* ... */
+ }
+}
+```
+
+### Note on authentication decorators
+- Authentication decorators can be used together and all of them **must** pass to the request be authenticated, but in the general case you don't need to (*and wouldn't like to...*) use all of them together, as you can code all of the authentication logic in the `@AuthenticateCondition` decorator.
+
+ ```ts
+ import {
+ RequireAllPermissions,
+ RequireSomePermission,
+ AuthenticateCondition,
+ } from '../../authentication/authentication.decorator';
+ import { Permissions } from '../../authentication/permissions.enum';
+ import { Waa, Baz } from './authenticationFunctions'
+
+ @Controller('foo')
+ @RequireAllPermissions(Permissions.FOO.USE, Permissions.FOO.REQUEST)
+ @RequireSomePermission(Permissions.FOO.MANAGE, Permissions.FOO.ADMIN)
+ @AuthenticateCondition(Waa)
+ @AuthenticateCondition(Baz)
+ class FooController {
+ /* ... */
+
+ @Get('bar')
+ async getBar() {
+ /* ... */
+ }
+
+ @Post('bar')
+ @RequireAllPermissions(Permissions.BAR.MANAGE, Permissions.BAR.USE, Permissions.BAR.REQUEST)
+ async postBar() {
+ /* ... */
+ }
+ }
+ ```
+
+- If `@RequireAllPermissions` and `@RequireSomePermission` are used with **only a single permission**, they present the **exactly same behavior**.
+
+ ```ts
+ // same behavior
+ @RequireAllPermissions(Permissions.BAR.MANAGE)
+ @RequireSomePermission(Permissions.BAR.MANAGE)
+ ```
+
+
+
+## `@User` parameter decorator
+The requesting user data can be obtained using the @User parameter decorator, like in the following snippet:
+
+```ts
+import { User, RequestUser } from '../../authentication/user.decorator';
+
+@Controller('foo')
+class FooController {
+ /* ... */
+
+ @Get('bar')
+ async getBar(@User() user: RequestUser) {
+ this.logger.info(user);
+
+ return { user };
+ }
+}
+```
+
+If the user is required to be logged in, set `required` to `true`, as you would want in the `change-password` operation:
+
+```ts
+import { User, RequestUser } from '../../authentication/user.decorator';
+
+@Controller('user')
+class UserController {
+ /* ... */
+
+ @Post('change-password')
+ @HttpCode(HttpStatus.OK)
+ async changePassword(
+ @User({ required: true }) user: RequestUser,
+ @Body() body: AuthChangePasswordRequest,
+ ) {
+ const { oldPassword, newPassword } = body;
+
+ return this.authClient.changePassword({
+ userId: user.user_id,
+ oldPassword,
+ newPassword,
+ });
+ }
+}
+```
+
+## 📦 Development
+### ⌨️ Coding Style
+By default, we use [ESLint](https://eslint.org/) + [Prettier](https://prettier.io/) with default settings.
+
+**We recommend using Visual Studio Code and installing the recommended extensions to ease the development process.**
+
+### Commits pattern
+Our workflow pipeline follows the conventional commits specs ([cheat sheets](https://cheatography.com/albelop/cheat-sheets/conventional-commits/)) to release versions accordingly.
+
+Format: `[optional scope]: `
+
+Example: `FIX: ensure Range headers adhere more closely to RFC 2616`
+
+### Branching naming convention
+- **Feature**: Any code changes for a new module or use case should be done on a feature branch. This branch is created based on the `main` branch. When all changes are done, a Pull Request/Merge Request is needed to put all of these changes back to the `main` branch. Examples: `feature/integrate-swagger`, `feature/JIRA-1234`, `feature/JIRA-1234_support-dark-theme`.
+
+ **It is recommended to use all lower caps letters and hyphen (-) to separate words unless it is a specific item name or ID. Underscore (_) could be used to separate the ID and description.**
+
+- **Bug Fix**: If the code changes made from the feature branch were rejected after a release, sprint or demo, any necessary fixes after that should be done on the bugfix branch. Examples: `bugfix/more-gray-shades`, `bugfix/JIRA-1444_gray-on-blur-fix`.
+
+- **Hot Fix**: If there is a need to fix a blocker, do a temporary patch, apply a critical framework or configuration change that should be handled immediately, it should be created as a Hotfix. Examples: `hotfix/disable-endpoint-zero-day-exploit`, `hotfix/increase-scaling-threshold`.
+
+- **Experimental**: A branch for playing around. Any new feature or idea that is not part of a release or a sprint. Example: `experimental/dark-theme-support`.
+
+### Making a Pull Request
+1. Commit your changes
+2. Open the Pull Request on GitHub
+3. Send Pull Request link in microsfera Google Chat Group for review and possible approval
+
+## 🛠️ Built with
+Some technologies used in this project:
+
+- [NestJS](https://docs.nestjs.com) - Framework for building efficient and scalable NodeJS server-side applications
+
+## ⚙️ Back-end Architecture
+The architecture can be found at [this link](https://sites.google.com/dadosfera.ai/wikidoproduto/time/back-end).