npm package: @laqus/base
Description: laqus base
Latest version: 1.5.11

This library is available as a [NPM package](https://www.npmjs.com/package/@laqus/base) and should be used as the foundation for any NestJS-based project to maintain standardization. Its code aims to be verbose to facilitate debugging and troubleshooting, as well as extensible, making it easy to create new features

## Requirements

### Env vars

As env vars que o seu projeto que está importando essa lib precisa ter são:

```dotenv
LAQUS_APP_NAME
APP_ENV_MODE    [localhost | develop | qa | staging | production]
LOG_LEVEL [DEBUG|VERBOSE|LOG|INFO|WARNING|CRITICAL|ERROR|FATAL]
CLUSTERS (optional)
```

## TO DOs

- [] Wiston integration for buffered logs


# Sobre esta lib

Esta lib faz uso de abstrações que facilitem a extensibilidade, substituições e design aberto. Por se tratarem de classes utilitárias, que podem ser usadas separadamente, a injeção de dependência deve ficar a cargo da aplicação que faz uso desta lib, invertendo-se assim as dependências.
Diferentes Loggers e outros serviços podem ser acoplados em runtime.

Ela está dividida em três partes principais:

```java
./application      //Classes relacionadas ao funcionamento da app
./domain           //Classes relacionadas ao dominio de dados/negocio
./infrastructure   //Classes relacionadas a logs, correlationId, integração com banco de dados, http clients, etc.
```

## Application

```java
./application                       
    ./models                    // service models
    ./presentation              //abstrações para camadas de presentation
        ./pagination            //abstrações de suporte à paginações
        ./rest                  //abstrações de suporte à serviços RESTful
            ./correlation-ids   //abstrações para uso do serviço de correlation em RESTful, como middlware, interceptor
            ./pipes             //parsers de entrada de dados para tipos especificos
            ./validators        //validadores para a entrada de dados
    ./repository                //abstrações de serviços de repository, transaction, etc
        ./abstractions              //abstrações para desacoplar lógicas de business das de databases
    ./service                       //classes de serviço
```

## Domain

```java
./domain                       
    ./interfaces    //abstrações para modelos de dados - Code First
```

## Infrastructure

```java
./correlation-ids       //abstrações para tratamento de correlações
./environment           //utilitários referente ao ambiente da application
./http                  //abstrações de client http
    ./axios             //implementação de axios. [Candidata a se tornar um novo package]
./logging               //abstrações de logs e levels
./system                //utilitários a nivel de sistema, suporte a clusterização, processes, memory, etc
./typeorm               //implementação de repo para TypeOrm [Candidato a se tornar novo package]
```

# Forma de utilização
A forma de tabalho ideal para esta lib é apenas mantermos as abstrações e talvez implementações principais. A ideia é manter sempre:
- Responsabilidade das classes unica
- Classes abertas para extensão e fechadas para modificação
- Interfaces coesas
- Inversão de dependencias

Novas implementações devem ser providas por novos packages. Por exemplo, uma implementação de persistência de dados para MongoDB deveria ser outro package. De MySQL, ou qualquer outro sgdb também. Para então ser utilizado na application de client. Ex.: Numa aplicação hipotética que precisa utilizar Prisma ou invés do TypeORM, teriamos como dependência:

```typescript
App Prisma
    package.json
        "dependencies": {
            "@laqus/base": "^6.6.6",
            "@laqus/prisma": "^1.2.3",
        }

Sendo que, no package @laqus/prisma, teriamos uma estrutura minimamente assim:

./infrastructure
    ./prisma
        ./utils      //utilitarios apenas deste package
        ./prisma-specifics  //objetos especificos para uso do Prisma
        abstract-prisma.repository.ts
        abstract-prisma.transaction.ts

Onde, estas ultimas classes deveriam implementar as abstrações do @laqus/base, tais como AbstractRepository<T> e AbstractTransaction:

export abstract class AbstractPrismaRepository<T extends IAbstractEntity> extends AbstractRepository<T> {}

export class PrismaTransaction extends AbstractTransaction {}

```

De modo a permitir que modulos de alto nivel dependam das abstrações de @laqus/base, pode ser necessário o uso de patterns como ServiceProvider (derivado Chain of responsability).
Para tal, abstrações puras, sem injeção de dependência como **ICorrelationIdService** ou **ILaqusLogger**, podem ter dependencias injetadas invertendo-se as dependencias de modo a deixar o código limpo, simples de entender e modificar através de seus providers: 

```typescript
export interface ICorrelationIdServiceProvider {
	getCorrelationIdService(): ICorrelationIdService;
}

export interface ILaqusLoggerServiceProvider {
	getLoggerService(): ILaqusLogger;
}
```

# Estrutura deste projeto

Este projeto faz uso do template de libs da Laqus, ou seja, ele é uma application que encapsula uma library.

Deste modo, é possível testar o uso, verificar o design das interfaces, extensões, etc, sem precisar poluir o codigo da library e sem precisar fazer a publicação dela.

Para rodar a aplicação host da library e debuggar, basta simplesmente usar o **F5** (no VsCode, profile padrão), ou manualmente, na aba de Debug.

```pascal
./laqus.base.js
    libs
        {@laqus/base}
            src
            index.ts
            {@laqus/base}.module.ts
            {@laqus/base}.service.ts
        package.json
        LICENSE.md
        README.md
    src
        app.controller.ts
        app.module.ts
        app.service.ts
        mais.ts

    package.json
    nest-cli.json
    tsconfig.json

```

## Publicação do package e versões

Este projeto contem o modelo de pipeline do gitlab configurado, bastando apenas:
- Incrementar a version do ./libs/base/package.json
- push - Sempre que for feito na main, um novo publish será feito no NPM.


## Build da lib para uso local

```shell
$ npm run build:lib
```