📝Core Repository

The contract that provides methods for repositories.

This is an abstract class and is used as a base for other modules.

Imports

import { CoreRepositoryContract } from 'niro-health';

Method of Use

To implement this class, you will need an create entity.

entities/index.ts
import { CoreEntityContract } from 'niro-health';

export class User extends CoreEntityContract {
  username: string;
  email: string;
  password: string;

  constructor(data: Partial<User>) {
    super(data);
    this.username = data?.username;
    this.email = data?.email;
    this.password = data?.password;
  }
}

You will need an implementation for the database.

contracts/index.ts
import { CoreDatabaseContract } from 'niro-health';
import type { User } from './entities';

export abstract class UserDatabaseContract extends CoreDatabaseContract<User> {
  abstract findByEmail(email: string): Promise<User | null>;
}

Let's create an in-memory bank by implementing our contract.

db/memory.ts
import type { INestApplication } from '@nestjs/common';
import type { ISimilarityFilterService, SimilarityFilterType as Type } from 'niro-health';
import type { User } from './entities';

import { UserDatabaseContract } from './contracts';

import * as _ from 'lodash';

export class UserMemoryDB extends UserDatacbaseContract {
  private readonly _similarityFilterService: ISimilarityFilterService;

  constructor(
    protected readonly app: INestApplication,
    private users: User[] = [],
  ) {
    super(app);
    this._similarityFilterService = this.app.get<ISimilarityFilterService>(
      'ISimilarityFilterService',
    );
  }

  async create(data: User): Promise<User> {
    this.users.push(data);

    return data;
  }

  async findAll(limit?: number, offset?: number): Promise<User[]> {
    return this.users.slice(offset || 0, limit || this.users.length);
  }

  async findOne(id: number | string): Promise<User | null> {
    return this.users.find((user) => user.id === id);
  }

  async findBy(filter: Partial<User>, similarity?: Type): Promise<User[]> {
    return this.users.filter((key) =>
      this._similarityFilterService.execute<User>(
        filter,
        key as User,
        similarity || 'full',
      ),
    ) as User[];
  }

  async findByEmail(email: string): Promise<User | null> {
    const hash = this.hashText(email);

    return this.users.find((user) => user.hash.email === hash);
  }

  async update(id: number | string, newData: User): Promise<User | null> {
    this.users = this.users.map((user) =>
      user.id === id ? { ...user, ..._.omitBy(newData, _.isNil) } : user,
    ) as User[];

    return await this.findOne(id);
  }

  async delete(id: number | string): Promise<boolean> {
    this.users = this.users.filter((user) => user.id !== id);

    return true;
  }
}

Create UseCases

To implement creating, updating, and deleting users, we should create use cases to make code maintenance and organization easier.

usecases/create.ts
import type { INestApplication } from '@nestjs/common';
import type { CreateUserDto } from './users/dto/create';
import { UserRepository } from './users/repositories';
import { UserDatabaseContract } from './users/contracts';
import { User } from './users/entities';

export class CreateUser {
  static async execute(
    user: CreateUserDto,
    database: UserDatabaseContract,
    app: INestApplication,
  ) {
    const repository = new UserRepository(database, app);
    const entity = new User({ id: database.generateUUID() });

    entity.username = user.username;
    entity.email = user.email;
    entity.password = user.password;

    return await repository.create(entity);
  }
}

Create Factories

Now we can implement a factory to group our use cases with our database implementations.

factories/create.ts
import type { INestApplication } from '@nestjs/common';
import type { CreateUserDto } from './users/dto/create';
import { CreateUser } from './users/usecases/create';
import { UserMemoryDB } from './users/db/memory';

export class CreateUserFactory {
  static async run(user: CreateUserDto, app: INestApplication) {
    const database = new UserMemoryDB(app);
    return await CreateUser.execute(user, database, app);
  }
}

Our implementation is complete.

Methods

Method
Scope
Description

beforeSave

abstract

This method is called before saving data to the database.

beforeUpdate

abstract

This method is called before updating data in the database.

create

abstract

This method is called for create new data in the database.

update

abstract

This method is called for update data in the database.

delete

abstract

This method is called for delete data in the database.

findById

abstract

This method is called for find data by id in the database.

findAll

abstract

This method is called for find all data in the database.

findBy

abstract

This method is called for find data by filter in the database.

Last updated